@marvalt/digivalt-core 0.2.16 โ†’ 0.2.21

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 CHANGED
@@ -5,6 +5,33 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.2.21] - 2026-06-18
9
+
10
+ ### Fixed
11
+ - Replaced unpublished **`/components`** bundle (leaked consumer `@/` shadcn aliases) with **`/integrations`**: `DigiValtTracker`, `MauticTracking`, `ChatwootWidget` only.
12
+ - **`@digivalt/tracker`** dependency uses npm **`^0.1.0`** (not `file:`).
13
+ - Smoke test devDependencies: **`react-router-dom`**, **`@tanstack/react-query`** (peer deps of bundled integrations).
14
+
15
+ ### Removed
16
+ - **`@marvalt/digivalt-core/components`** export (never successfully published).
17
+
18
+ ## [0.2.19] - 2026-05-30
19
+
20
+ ### Added
21
+ - Required dependency **`@digivalt/tracker`** (Google Analytics + Matomo paste-in snippets).
22
+ - Re-export **`DigiValtTracker`** from **`@marvalt/digivalt-core/components`** (browser-safe entry; main package export includes Node generators).
23
+ - New subpath export **`@marvalt/digivalt-core/components`** for React UI integrations.
24
+ - Template **`DIGIVALT_SETUP.md`** analytics section; **`deploy-secrets`** allowlist extended for `VITE_GA_*`, `VITE_MATOMO_*`, `VITE_TRACKING_*`.
25
+
26
+ ## [0.2.17] - 2026-05-29
27
+
28
+ ### Added
29
+ - **`docs/README.md`:** documentation index for developers and AI agents (links ENVIRONMENT, SEO, bootstrap docs, and adapter packages).
30
+ - Publish **`verify-pack`** guard ensures README and docs ship in npm tarball.
31
+
32
+ ### Changed
33
+ - **`docs/ENVIRONMENT.md`:** React 19 install note (`legacy-peer-deps` / `.npmrc`) for `react-helmet-async` peer resolution.
34
+
8
35
  ## [0.2.16] - 2026-05-29
9
36
 
10
37
  ### Changed
package/README.md CHANGED
@@ -8,7 +8,7 @@ Core DigiVAlt package for static data generation, runtime service wiring, and Cl
8
8
  npm install @marvalt/digivalt-core
9
9
  ```
10
10
 
11
- Full handover reference for env vars (developers and DevOps): **[docs/ENVIRONMENT.md](./docs/ENVIRONMENT.md)**.
11
+ Full handover docs: **[docs/README.md](./docs/README.md)** and **[docs/ENVIRONMENT.md](./docs/ENVIRONMENT.md)**. After install: `node_modules/@marvalt/digivalt-core/docs/README.md`.
12
12
 
13
13
  In the **DigiVAlt monorepo**, **`digivalt-landing`** is the reference Vite app used to test this package with WordPress plugins and Cloudflare Pages.
14
14
 
@@ -1,5 +1,6 @@
1
1
  export * from './integrations/chatwoot-widget';
2
2
  export * from './integrations/mautic-tracking';
3
+ export * from './integrations/digivalt-tracker';
3
4
  export * from './WordPressFooter';
4
5
  export * from './organisms/StaticGravityForm';
5
6
  export * from './organisms/MauticForm';
@@ -0,0 +1 @@
1
+ export { DigiValtTracker } from '@digivalt/tracker';
@@ -3,19 +3,25 @@ import { GravityFormField } from '../services/gravityForms';
3
3
  /**
4
4
  * Custom hook for fetching all Gravity Forms
5
5
  */
6
- export declare const useGravityForms: () => any;
6
+ export declare const useGravityForms: () => import("@tanstack/react-query").UseQueryResult<any, Error>;
7
7
  /**
8
8
  * Custom hook for fetching a specific Gravity Form
9
9
  */
10
- export declare const useGravityForm: (formId: string) => any;
10
+ export declare const useGravityForm: (formId: string) => import("@tanstack/react-query").UseQueryResult<any, Error>;
11
11
  /**
12
12
  * Custom hook for fetching a Gravity Form schema for rendering
13
13
  */
14
- export declare const useGravityFormSchema: (formId: string) => any;
14
+ export declare const useGravityFormSchema: (formId: string) => import("@tanstack/react-query").UseQueryResult<any, Error>;
15
15
  /**
16
16
  * Custom hook for submitting Gravity Forms
17
17
  */
18
- export declare const useGravityFormSubmission: () => any;
18
+ export declare const useGravityFormSubmission: () => import("@tanstack/react-query").UseMutationResult<import("@marvalt/wadapter").GravityFormSubmissionResult, Error, {
19
+ formId: string;
20
+ entry: GravityFormEntry;
21
+ files?: {
22
+ [fieldId: string]: File[];
23
+ };
24
+ }, unknown>;
19
25
  /**
20
26
  * Custom hook for fetching Gravity Form entries
21
27
  */
@@ -25,11 +31,11 @@ export declare const useGravityFormEntries: (formId: string, params?: {
25
31
  search?: string;
26
32
  start_date?: string;
27
33
  end_date?: string;
28
- }) => any;
34
+ }) => import("@tanstack/react-query").UseQueryResult<any, Error>;
29
35
  /**
30
36
  * Custom hook for fetching a specific Gravity Form entry
31
37
  */
32
- export declare const useGravityFormEntry: (entryId: string) => any;
38
+ export declare const useGravityFormEntry: (entryId: string) => import("@tanstack/react-query").UseQueryResult<any, Error>;
33
39
  /**
34
40
  * Custom hook for form validation
35
41
  */
@@ -1,24 +1,27 @@
1
1
  /**
2
2
  * Custom hook for fetching all Gravity Forms using static data
3
3
  */
4
- export declare const useGravityForms: () => any;
4
+ export declare const useGravityForms: () => import("@tanstack/react-query").UseQueryResult<NoInfer<import("../data/gravityFormsDataStore").GravityForm[]>, Error>;
5
5
  /**
6
6
  * Custom hook for fetching a specific Gravity Form using static data
7
7
  */
8
- export declare const useGravityForm: (formId: string) => any;
8
+ export declare const useGravityForm: (formId: string) => import("@tanstack/react-query").UseQueryResult<NoInfer<import("../data/gravityFormsDataStore").GravityForm>, Error>;
9
9
  /**
10
10
  * Custom hook for fetching a Gravity Form schema for rendering using static data
11
11
  */
12
- export declare const useGravityFormSchema: (formId: string) => any;
12
+ export declare const useGravityFormSchema: (formId: string) => import("@tanstack/react-query").UseQueryResult<NoInfer<import("../data/gravityFormsDataStore").GravityForm>, Error>;
13
13
  /**
14
14
  * Custom hook for submitting Gravity Forms using the npm package
15
15
  */
16
- export declare const useGravityFormSubmission: () => any;
16
+ export declare const useGravityFormSubmission: () => import("@tanstack/react-query").UseMutationResult<any, Error, {
17
+ formId: string;
18
+ values: Record<string, any>;
19
+ }, unknown>;
17
20
  /**
18
21
  * Custom hook for Gravity Form submissions using the npm package
19
22
  */
20
- export declare const useGravityFormSubmissions: (formId: string) => any;
23
+ export declare const useGravityFormSubmissions: (formId: string) => import("@tanstack/react-query").UseQueryResult<NoInfer<any[]>, Error>;
21
24
  /**
22
25
  * Custom hook for Gravity Form entries using the npm package
23
26
  */
24
- export declare const useGravityFormEntries: (formId: string, page?: number, perPage?: number) => any;
27
+ export declare const useGravityFormEntries: (formId: string, page?: number, perPage?: number) => import("@tanstack/react-query").UseQueryResult<NoInfer<any[]>, Error>;
@@ -1,11 +1,15 @@
1
+ import { SuiteCRMLead, SuiteCRMContact, SuiteCRMAccount, SuiteCRMOpportunity } from '../services/suitecrm';
1
2
  /**
2
3
  * Custom hook for creating SuiteCRM leads
3
4
  */
4
- export declare const useSuiteCRMCreateLead: () => any;
5
+ export declare const useSuiteCRMCreateLead: () => import("@tanstack/react-query").UseMutationResult<import("../services").SuiteCRMAPIResponse<any>, Error, SuiteCRMLead, unknown>;
5
6
  /**
6
7
  * Custom hook for updating SuiteCRM leads
7
8
  */
8
- export declare const useSuiteCRMUpdateLead: () => any;
9
+ export declare const useSuiteCRMUpdateLead: () => import("@tanstack/react-query").UseMutationResult<import("../services").SuiteCRMAPIResponse<any>, Error, {
10
+ leadId: string;
11
+ lead: Partial<SuiteCRMLead>;
12
+ }, unknown>;
9
13
  /**
10
14
  * Custom hook for fetching SuiteCRM leads
11
15
  */
@@ -14,52 +18,55 @@ export declare const useSuiteCRMLeads: (params?: {
14
18
  per_page?: number;
15
19
  filter?: string;
16
20
  sort?: string;
17
- }) => any;
21
+ }) => import("@tanstack/react-query").UseQueryResult<NoInfer<import("../services").SuiteCRMAPIResponse<any>>, Error>;
18
22
  /**
19
23
  * Custom hook for fetching a specific SuiteCRM lead
20
24
  */
21
- export declare const useSuiteCRMLead: (leadId: string) => any;
25
+ export declare const useSuiteCRMLead: (leadId: string) => import("@tanstack/react-query").UseQueryResult<NoInfer<import("../services").SuiteCRMAPIResponse<any>>, Error>;
22
26
  /**
23
27
  * Custom hook for searching SuiteCRM leads
24
28
  */
25
- export declare const useSuiteCRMSearchLeads: (query: string) => any;
29
+ export declare const useSuiteCRMSearchLeads: (query: string) => import("@tanstack/react-query").UseQueryResult<NoInfer<import("../services").SuiteCRMAPIResponse<any>>, Error>;
26
30
  /**
27
31
  * Custom hook for creating SuiteCRM contacts
28
32
  */
29
- export declare const useSuiteCRMCreateContact: () => any;
33
+ export declare const useSuiteCRMCreateContact: () => import("@tanstack/react-query").UseMutationResult<import("../services").SuiteCRMAPIResponse<any>, Error, SuiteCRMContact, unknown>;
30
34
  /**
31
35
  * Custom hook for updating SuiteCRM contacts
32
36
  */
33
- export declare const useSuiteCRMUpdateContact: () => any;
37
+ export declare const useSuiteCRMUpdateContact: () => import("@tanstack/react-query").UseMutationResult<import("../services").SuiteCRMAPIResponse<any>, Error, {
38
+ contactId: string;
39
+ contact: Partial<SuiteCRMContact>;
40
+ }, unknown>;
34
41
  /**
35
42
  * Custom hook for fetching a specific SuiteCRM contact
36
43
  */
37
- export declare const useSuiteCRMContact: (contactId: string) => any;
44
+ export declare const useSuiteCRMContact: (contactId: string) => import("@tanstack/react-query").UseQueryResult<NoInfer<import("../services").SuiteCRMAPIResponse<any>>, Error>;
38
45
  /**
39
46
  * Custom hook for creating SuiteCRM accounts
40
47
  */
41
- export declare const useSuiteCRMCreateAccount: () => any;
48
+ export declare const useSuiteCRMCreateAccount: () => import("@tanstack/react-query").UseMutationResult<import("../services").SuiteCRMAPIResponse<any>, Error, SuiteCRMAccount, unknown>;
42
49
  /**
43
50
  * Custom hook for fetching a specific SuiteCRM account
44
51
  */
45
- export declare const useSuiteCRMAccount: (accountId: string) => any;
52
+ export declare const useSuiteCRMAccount: (accountId: string) => import("@tanstack/react-query").UseQueryResult<NoInfer<import("../services").SuiteCRMAPIResponse<any>>, Error>;
46
53
  /**
47
54
  * Custom hook for creating SuiteCRM opportunities
48
55
  */
49
- export declare const useSuiteCRMCreateOpportunity: () => any;
56
+ export declare const useSuiteCRMCreateOpportunity: () => import("@tanstack/react-query").UseMutationResult<import("../services").SuiteCRMAPIResponse<any>, Error, SuiteCRMOpportunity, unknown>;
50
57
  /**
51
58
  * Custom hook for fetching a specific SuiteCRM opportunity
52
59
  */
53
- export declare const useSuiteCRMOpportunity: (opportunityId: string) => any;
60
+ export declare const useSuiteCRMOpportunity: (opportunityId: string) => import("@tanstack/react-query").UseQueryResult<NoInfer<import("../services").SuiteCRMAPIResponse<any>>, Error>;
54
61
  /**
55
62
  * Custom hook for fetching SuiteCRM lead sources
56
63
  */
57
- export declare const useSuiteCRMLeadSources: () => any;
64
+ export declare const useSuiteCRMLeadSources: () => import("@tanstack/react-query").UseQueryResult<NoInfer<import("../services").SuiteCRMAPIResponse<any>>, Error>;
58
65
  /**
59
66
  * Custom hook for fetching SuiteCRM lead statuses
60
67
  */
61
- export declare const useSuiteCRMLeadStatuses: () => any;
68
+ export declare const useSuiteCRMLeadStatuses: () => import("@tanstack/react-query").UseQueryResult<NoInfer<import("../services").SuiteCRMAPIResponse<any>>, Error>;
62
69
  /**
63
70
  * Custom hook for testing SuiteCRM connection
64
71
  */
65
- export declare const useSuiteCRMConnectionTest: () => any;
72
+ export declare const useSuiteCRMConnectionTest: () => import("@tanstack/react-query").UseQueryResult<boolean, Error>;
@@ -0,0 +1,3 @@
1
+ export { DigiValtTracker } from './components/integrations/digivalt-tracker';
2
+ export { default as MauticTracking } from './components/integrations/mautic-tracking';
3
+ export { ChatwootWidget } from './components/integrations/chatwoot-widget';
@@ -0,0 +1,316 @@
1
+ 'use strict';
2
+
3
+ var tracker = require('@digivalt/tracker');
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+ var madapter = require('@marvalt/madapter');
6
+ var React = require('react');
7
+
8
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
9
+ const getImportMetaEnv = () => {
10
+ try {
11
+ return typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('integrations.cjs', document.baseURI).href)) }) !== 'undefined' ? undefined : undefined;
12
+ }
13
+ catch {
14
+ return undefined;
15
+ }
16
+ };
17
+ const getEnv = (key) => {
18
+ const viteEnv = getImportMetaEnv();
19
+ if (viteEnv && key in viteEnv) {
20
+ const value = viteEnv[key];
21
+ return value == null ? undefined : String(value);
22
+ }
23
+ if (typeof process !== 'undefined' && process.env && key in process.env) {
24
+ const value = process.env[key];
25
+ return value == null ? undefined : String(value);
26
+ }
27
+ return undefined;
28
+ };
29
+ const isDevEnvironment = () => {
30
+ const viteEnv = getImportMetaEnv();
31
+ if (viteEnv && 'DEV' in viteEnv) {
32
+ return Boolean(viteEnv.DEV);
33
+ }
34
+ return typeof process !== 'undefined' && process.env?.NODE_ENV === 'development';
35
+ };
36
+
37
+ // Detect if we're running in a local development environment
38
+ const isLocalDevelopment = () => {
39
+ // Check if we're in a browser environment
40
+ if (typeof window !== 'undefined') {
41
+ // Check for local development indicators
42
+ const isLocalhost = window.location.hostname === 'localhost' ||
43
+ window.location.hostname === '127.0.0.1' ||
44
+ window.location.hostname.includes('192.168.') ||
45
+ window.location.hostname.includes('10.0.');
46
+ const isDevPort = window.location.port === '3000' ||
47
+ window.location.port === '5173' ||
48
+ window.location.port === '8080';
49
+ const hasLocalEnv = Boolean(getEnv('DEV')) || getEnv('VITE_LOCAL_DEVELOPMENT') === 'true';
50
+ return Boolean(isLocalhost && (isDevPort || hasLocalEnv));
51
+ }
52
+ else {
53
+ // Node.js environment - check environment variables
54
+ return getEnv('NODE_ENV') === 'development' ||
55
+ getEnv('VITE_LOCAL_DEVELOPMENT') === 'true';
56
+ }
57
+ };
58
+ // Get the appropriate environment configuration
59
+ const getEnvironmentConfig = () => {
60
+ const isLocal = isLocalDevelopment();
61
+ // Default to cloudflare_proxy (via Cloudflare Pages Functions)
62
+ // Use 'direct' only for local development with whitelisted IPs
63
+ const authModeRaw = getEnv('VITE_AUTH_MODE');
64
+ const authMode = authModeRaw || 'cloudflare_proxy';
65
+ // Reduced debug logging - only in development and only once
66
+ if (isDevEnvironment() && !authModeRaw) {
67
+ console.log('โ„น๏ธ VITE_AUTH_MODE not set, defaulting to cloudflare_proxy (Cloudflare Pages Functions)');
68
+ }
69
+ // Validate auth mode value
70
+ if (authMode !== 'direct' && authMode !== 'cloudflare_proxy') {
71
+ console.error('โŒ Invalid VITE_AUTH_MODE value. Must be "direct" or "cloudflare_proxy".');
72
+ return {
73
+ mode: 'error',
74
+ authMode: 'error',
75
+ dataSource: 'static',
76
+ baseUrl: '',
77
+ headers: {},
78
+ description: `Invalid configuration - VITE_AUTH_MODE="${authModeRaw}"`,
79
+ suiteCRM: {
80
+ url: undefined,
81
+ proxyUrl: undefined,
82
+ appId: undefined,
83
+ workerSecret: undefined,
84
+ oauth2: {
85
+ clientId: undefined,
86
+ clientSecret: undefined,
87
+ tokenUrl: undefined,
88
+ username: undefined,
89
+ password: undefined,
90
+ },
91
+ }
92
+ };
93
+ }
94
+ // Cloudflare proxy mode (uses Cloudflare Pages Functions by default)
95
+ // Worker URL is optional - Pages Functions handle routing automatically
96
+ if (authMode === 'cloudflare_proxy') {
97
+ const workerUrl = getEnv('VITE_CLOUDFLARE_WORKER_URL');
98
+ // Cloudflare Pages Functions work without explicit worker URL
99
+ // The worker URL is only needed for separate Cloudflare Workers
100
+ // Pages Functions automatically handle /api/* routes
101
+ const baseUrl = workerUrl || '/api';
102
+ return {
103
+ mode: isLocal ? 'local' : 'remote',
104
+ authMode: 'cloudflare_proxy',
105
+ dataSource: 'static',
106
+ baseUrl,
107
+ headers: {
108
+ 'Content-Type': 'application/json'
109
+ },
110
+ description: workerUrl
111
+ ? (isLocal ? 'Local development with Cloudflare Worker proxy' : 'Remote development with Cloudflare Worker proxy')
112
+ : (isLocal ? 'Local development with Cloudflare Pages Functions' : 'Production with Cloudflare Pages Functions'),
113
+ mautic: {
114
+ proxyUrl: getEnv('VITE_MAUTIC_PROXY_URL')
115
+ },
116
+ suiteCRM: {
117
+ url: getEnv('VITE_SUITECRM_URL'),
118
+ proxyUrl: getEnv('VITE_SUITECRM_PROXY_URL'),
119
+ appId: undefined,
120
+ workerSecret: undefined,
121
+ oauth2: {
122
+ clientId: getEnv('VITE_SUITECRM_CLIENT_ID'),
123
+ clientSecret: getEnv('VITE_SUITECRM_CLIENT_SECRET'),
124
+ tokenUrl: getEnv('VITE_SUITECRM_TOKEN_URL'),
125
+ username: getEnv('VITE_SUITECRM_USERNAME'),
126
+ password: getEnv('VITE_SUITECRM_PASSWORD'),
127
+ },
128
+ }
129
+ };
130
+ }
131
+ // Direct WordPress mode (legacy - for local development only)
132
+ if (authMode === 'direct') {
133
+ const wpApiUrl = getEnv('VITE_WORDPRESS_API_URL');
134
+ if (!wpApiUrl) {
135
+ console.warn('โš ๏ธ Direct mode requires: VITE_WORDPRESS_API_URL');
136
+ return {
137
+ mode: 'error',
138
+ authMode: 'error',
139
+ dataSource: 'static',
140
+ baseUrl: '',
141
+ headers: {},
142
+ description: 'Invalid configuration - missing WordPress API URL',
143
+ suiteCRM: {
144
+ url: undefined,
145
+ proxyUrl: undefined,
146
+ appId: undefined,
147
+ workerSecret: undefined,
148
+ oauth2: {
149
+ clientId: undefined,
150
+ clientSecret: undefined,
151
+ tokenUrl: undefined,
152
+ username: undefined,
153
+ password: undefined,
154
+ },
155
+ }
156
+ };
157
+ }
158
+ if (isDevEnvironment()) {
159
+ console.log('๐Ÿ” Using direct WordPress mode (legacy - for local development only)');
160
+ }
161
+ const localDev = getEnv('VITE_LOCAL_DEVELOPMENT') === 'true';
162
+ return {
163
+ mode: localDev ? 'local' : 'remote',
164
+ authMode: 'direct',
165
+ dataSource: 'hybrid',
166
+ baseUrl: wpApiUrl,
167
+ headers: { 'Content-Type': 'application/json' },
168
+ description: localDev ? 'Direct (local dev) without Access' : 'Direct mode',
169
+ mautic: { url: getEnv('VITE_MAUTIC_URL') },
170
+ suiteCRM: {
171
+ url: getEnv('VITE_SUITECRM_URL'),
172
+ proxyUrl: getEnv('VITE_SUITECRM_PROXY_URL'),
173
+ appId: undefined,
174
+ workerSecret: undefined,
175
+ oauth2: {
176
+ clientId: getEnv('VITE_SUITECRM_CLIENT_ID'),
177
+ clientSecret: getEnv('VITE_SUITECRM_CLIENT_SECRET'),
178
+ tokenUrl: getEnv('VITE_SUITECRM_TOKEN_URL'),
179
+ username: getEnv('VITE_SUITECRM_USERNAME'),
180
+ password: getEnv('VITE_SUITECRM_PASSWORD'),
181
+ },
182
+ }
183
+ };
184
+ }
185
+ // This should never be reached, but just in case
186
+ return {
187
+ mode: 'error',
188
+ authMode: 'error',
189
+ dataSource: 'static',
190
+ baseUrl: '',
191
+ headers: {},
192
+ description: 'Invalid configuration - unknown error',
193
+ suiteCRM: {
194
+ url: undefined,
195
+ proxyUrl: undefined,
196
+ appId: undefined,
197
+ workerSecret: undefined,
198
+ oauth2: {
199
+ clientId: undefined,
200
+ clientSecret: undefined,
201
+ tokenUrl: undefined,
202
+ username: undefined,
203
+ password: undefined,
204
+ },
205
+ }
206
+ };
207
+ };
208
+ // Environment status and diagnostics
209
+ const getEnvironmentStatus = () => {
210
+ const config = getEnvironmentConfig();
211
+ const isLocal = isLocalDevelopment();
212
+ const authMode = getEnv('VITE_AUTH_MODE');
213
+ // Check if required credentials are available for each mode
214
+ const hasCloudflareCredentials = !!getEnv('VITE_CLOUDFLARE_WORKER_URL');
215
+ const hasWordPressApiUrl = !!getEnv('VITE_WORDPRESS_API_URL');
216
+ return {
217
+ currentConfig: config,
218
+ diagnostics: {
219
+ isLocalDevelopment: isLocal,
220
+ authMode: authMode,
221
+ hasCloudflareCredentials,
222
+ hasWordpressApiUrl: hasWordPressApiUrl,
223
+ cloudflareWorkerUrl: !!getEnv('VITE_CLOUDFLARE_WORKER_URL'),
224
+ cfAccessId: !!getEnv('VITE_CF_ACCESS_CLIENT_ID'),
225
+ cfAccessSecret: !!getEnv('VITE_CF_ACCESS_CLIENT_SECRET'),
226
+ mauticProxyUrl: !!getEnv('VITE_MAUTIC_PROXY_URL')
227
+ },
228
+ recommendations: {
229
+ // Only show recommendation if authMode is explicitly set to an invalid value
230
+ // Default is cloudflare_proxy, so no recommendation needed if not set
231
+ authMode: null, // Defaults to cloudflare_proxy, no warning needed
232
+ cloudflare: null // Pages Functions work without explicit worker URL
233
+ }
234
+ };
235
+ };
236
+ // Export current environment config as default
237
+ getEnvironmentConfig();
238
+ getEnvironmentStatus();
239
+
240
+ const MauticTracking = ({ enabled, mauticUrl, proxyUrl }) => {
241
+ // Get configuration from environment config
242
+ const envConfig = getEnvironmentConfig();
243
+ const isEnabled = enabled ?? (envConfig.authMode === 'cloudflare_proxy' && !!envConfig.mautic?.proxyUrl);
244
+ const trackingUrl = mauticUrl ?? envConfig.mautic?.url;
245
+ const trackingProxyUrl = proxyUrl ?? envConfig.mautic?.proxyUrl;
246
+ // Use the package component
247
+ return (jsxRuntime.jsx(madapter.MauticTracking, { enabled: isEnabled, mauticUrl: trackingUrl, proxyUrl: trackingProxyUrl }));
248
+ };
249
+
250
+ // @ts-nocheck
251
+ const ChatwootWidget = React.forwardRef(({ config, enabled = true, className, }, ref) => {
252
+ const scriptLoaded = React.useRef(false);
253
+ const widgetInitialized = React.useRef(false);
254
+ React.useEffect(() => {
255
+ if (!enabled || scriptLoaded.current)
256
+ return;
257
+ // Load Chatwoot script
258
+ const script = document.createElement('script');
259
+ script.src = `${config.baseUrl || 'https://app.chatwoot.com'}/packs/js/sdk.js`;
260
+ script.async = true;
261
+ script.defer = true;
262
+ script.onload = () => {
263
+ scriptLoaded.current = true;
264
+ initializeWidget();
265
+ };
266
+ document.head.appendChild(script);
267
+ return () => {
268
+ // Cleanup script if component unmounts before loading
269
+ if (document.head.contains(script)) {
270
+ document.head.removeChild(script);
271
+ }
272
+ };
273
+ }, [enabled, config.baseUrl]);
274
+ React.useEffect(() => {
275
+ if (scriptLoaded.current && !widgetInitialized.current) {
276
+ initializeWidget();
277
+ }
278
+ }, [config]);
279
+ const initializeWidget = () => {
280
+ if (widgetInitialized.current || !window.chatwootSDK)
281
+ return;
282
+ // Set global settings
283
+ window.chatwootSettings = {
284
+ hideMessageBubble: config.hideMessageBubble,
285
+ position: config.position,
286
+ locale: config.locale,
287
+ type: config.type,
288
+ launcherTitle: config.launcherTitle,
289
+ showPopoutButton: config.showPopoutButton,
290
+ };
291
+ // Initialize the widget
292
+ window.chatwootSDK.run({
293
+ websiteToken: config.websiteToken,
294
+ baseUrl: config.baseUrl || 'https://app.chatwoot.com',
295
+ });
296
+ widgetInitialized.current = true;
297
+ };
298
+ // Expose widget controls
299
+ React.useImperativeHandle(ref, () => ({
300
+ toggle: () => window.chatwootSDK?.toggle(),
301
+ show: () => window.chatwootSDK?.show(),
302
+ hide: () => window.chatwootSDK?.hide(),
303
+ reset: () => window.chatwootSDK?.reset(),
304
+ }));
305
+ // Don't render anything in the DOM - Chatwoot creates its own elements
306
+ return null;
307
+ });
308
+ ChatwootWidget.displayName = 'ChatwootWidget';
309
+
310
+ Object.defineProperty(exports, "DigiValtTracker", {
311
+ enumerable: true,
312
+ get: function () { return tracker.DigiValtTracker; }
313
+ });
314
+ exports.ChatwootWidget = ChatwootWidget;
315
+ exports.MauticTracking = MauticTracking;
316
+ //# sourceMappingURL=integrations.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integrations.cjs","sources":["../src/runtime/env.ts","../src/config/environment.ts","../src/components/integrations/mautic-tracking.tsx","../src/components/integrations/chatwoot-widget.tsx"],"sourcesContent":[null,null,null,null],"names":["_jsx","MauticTrackingComponent","forwardRef","useRef","useEffect"],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ export { DigiValtTracker } from '@digivalt/tracker';
2
+ import React$1 from 'react';
3
+
4
+ interface MauticTrackingProps {
5
+ enabled?: boolean;
6
+ mauticUrl?: string;
7
+ proxyUrl?: string;
8
+ appId?: string;
9
+ workerSecret?: string;
10
+ }
11
+ declare const MauticTracking: React.FC<MauticTrackingProps>;
12
+
13
+ interface ChatwootConfig {
14
+ websiteToken: string;
15
+ baseUrl?: string;
16
+ locale?: string;
17
+ type?: 'standard' | 'expanded_bubble';
18
+ launcherTitle?: string;
19
+ hideMessageBubble?: boolean;
20
+ position?: 'left' | 'right';
21
+ showPopoutButton?: boolean;
22
+ }
23
+ interface ChatwootWidgetProps {
24
+ config: ChatwootConfig;
25
+ enabled?: boolean;
26
+ className?: string;
27
+ }
28
+ interface ChatwootWidgetRef {
29
+ toggle: () => void;
30
+ show: () => void;
31
+ hide: () => void;
32
+ reset: () => void;
33
+ }
34
+ declare global {
35
+ interface Window {
36
+ chatwootSettings: {
37
+ hideMessageBubble?: boolean;
38
+ position?: 'left' | 'right';
39
+ locale?: string;
40
+ type?: 'standard' | 'expanded_bubble';
41
+ launcherTitle?: string;
42
+ showPopoutButton?: boolean;
43
+ };
44
+ chatwootSDK: {
45
+ run: (config: any) => void;
46
+ toggle: () => void;
47
+ show: () => void;
48
+ hide: () => void;
49
+ reset: () => void;
50
+ };
51
+ }
52
+ }
53
+ declare const ChatwootWidget: React$1.ForwardRefExoticComponent<ChatwootWidgetProps & React$1.RefAttributes<ChatwootWidgetRef>>;
54
+
55
+ export { ChatwootWidget, MauticTracking };
@@ -0,0 +1,308 @@
1
+ export { DigiValtTracker } from '@digivalt/tracker';
2
+ import { jsx } from 'react/jsx-runtime';
3
+ import { MauticTracking as MauticTracking$1 } from '@marvalt/madapter';
4
+ import React, { forwardRef, useRef, useEffect } from 'react';
5
+
6
+ const getImportMetaEnv = () => {
7
+ try {
8
+ return typeof import.meta !== 'undefined' ? import.meta.env : undefined;
9
+ }
10
+ catch {
11
+ return undefined;
12
+ }
13
+ };
14
+ const getEnv = (key) => {
15
+ const viteEnv = getImportMetaEnv();
16
+ if (viteEnv && key in viteEnv) {
17
+ const value = viteEnv[key];
18
+ return value == null ? undefined : String(value);
19
+ }
20
+ if (typeof process !== 'undefined' && process.env && key in process.env) {
21
+ const value = process.env[key];
22
+ return value == null ? undefined : String(value);
23
+ }
24
+ return undefined;
25
+ };
26
+ const isDevEnvironment = () => {
27
+ const viteEnv = getImportMetaEnv();
28
+ if (viteEnv && 'DEV' in viteEnv) {
29
+ return Boolean(viteEnv.DEV);
30
+ }
31
+ return typeof process !== 'undefined' && process.env?.NODE_ENV === 'development';
32
+ };
33
+
34
+ // Detect if we're running in a local development environment
35
+ const isLocalDevelopment = () => {
36
+ // Check if we're in a browser environment
37
+ if (typeof window !== 'undefined') {
38
+ // Check for local development indicators
39
+ const isLocalhost = window.location.hostname === 'localhost' ||
40
+ window.location.hostname === '127.0.0.1' ||
41
+ window.location.hostname.includes('192.168.') ||
42
+ window.location.hostname.includes('10.0.');
43
+ const isDevPort = window.location.port === '3000' ||
44
+ window.location.port === '5173' ||
45
+ window.location.port === '8080';
46
+ const hasLocalEnv = Boolean(getEnv('DEV')) || getEnv('VITE_LOCAL_DEVELOPMENT') === 'true';
47
+ return Boolean(isLocalhost && (isDevPort || hasLocalEnv));
48
+ }
49
+ else {
50
+ // Node.js environment - check environment variables
51
+ return getEnv('NODE_ENV') === 'development' ||
52
+ getEnv('VITE_LOCAL_DEVELOPMENT') === 'true';
53
+ }
54
+ };
55
+ // Get the appropriate environment configuration
56
+ const getEnvironmentConfig = () => {
57
+ const isLocal = isLocalDevelopment();
58
+ // Default to cloudflare_proxy (via Cloudflare Pages Functions)
59
+ // Use 'direct' only for local development with whitelisted IPs
60
+ const authModeRaw = getEnv('VITE_AUTH_MODE');
61
+ const authMode = authModeRaw || 'cloudflare_proxy';
62
+ // Reduced debug logging - only in development and only once
63
+ if (isDevEnvironment() && !authModeRaw) {
64
+ console.log('โ„น๏ธ VITE_AUTH_MODE not set, defaulting to cloudflare_proxy (Cloudflare Pages Functions)');
65
+ }
66
+ // Validate auth mode value
67
+ if (authMode !== 'direct' && authMode !== 'cloudflare_proxy') {
68
+ console.error('โŒ Invalid VITE_AUTH_MODE value. Must be "direct" or "cloudflare_proxy".');
69
+ return {
70
+ mode: 'error',
71
+ authMode: 'error',
72
+ dataSource: 'static',
73
+ baseUrl: '',
74
+ headers: {},
75
+ description: `Invalid configuration - VITE_AUTH_MODE="${authModeRaw}"`,
76
+ suiteCRM: {
77
+ url: undefined,
78
+ proxyUrl: undefined,
79
+ appId: undefined,
80
+ workerSecret: undefined,
81
+ oauth2: {
82
+ clientId: undefined,
83
+ clientSecret: undefined,
84
+ tokenUrl: undefined,
85
+ username: undefined,
86
+ password: undefined,
87
+ },
88
+ }
89
+ };
90
+ }
91
+ // Cloudflare proxy mode (uses Cloudflare Pages Functions by default)
92
+ // Worker URL is optional - Pages Functions handle routing automatically
93
+ if (authMode === 'cloudflare_proxy') {
94
+ const workerUrl = getEnv('VITE_CLOUDFLARE_WORKER_URL');
95
+ // Cloudflare Pages Functions work without explicit worker URL
96
+ // The worker URL is only needed for separate Cloudflare Workers
97
+ // Pages Functions automatically handle /api/* routes
98
+ const baseUrl = workerUrl || '/api';
99
+ return {
100
+ mode: isLocal ? 'local' : 'remote',
101
+ authMode: 'cloudflare_proxy',
102
+ dataSource: 'static',
103
+ baseUrl,
104
+ headers: {
105
+ 'Content-Type': 'application/json'
106
+ },
107
+ description: workerUrl
108
+ ? (isLocal ? 'Local development with Cloudflare Worker proxy' : 'Remote development with Cloudflare Worker proxy')
109
+ : (isLocal ? 'Local development with Cloudflare Pages Functions' : 'Production with Cloudflare Pages Functions'),
110
+ mautic: {
111
+ proxyUrl: getEnv('VITE_MAUTIC_PROXY_URL')
112
+ },
113
+ suiteCRM: {
114
+ url: getEnv('VITE_SUITECRM_URL'),
115
+ proxyUrl: getEnv('VITE_SUITECRM_PROXY_URL'),
116
+ appId: undefined,
117
+ workerSecret: undefined,
118
+ oauth2: {
119
+ clientId: getEnv('VITE_SUITECRM_CLIENT_ID'),
120
+ clientSecret: getEnv('VITE_SUITECRM_CLIENT_SECRET'),
121
+ tokenUrl: getEnv('VITE_SUITECRM_TOKEN_URL'),
122
+ username: getEnv('VITE_SUITECRM_USERNAME'),
123
+ password: getEnv('VITE_SUITECRM_PASSWORD'),
124
+ },
125
+ }
126
+ };
127
+ }
128
+ // Direct WordPress mode (legacy - for local development only)
129
+ if (authMode === 'direct') {
130
+ const wpApiUrl = getEnv('VITE_WORDPRESS_API_URL');
131
+ if (!wpApiUrl) {
132
+ console.warn('โš ๏ธ Direct mode requires: VITE_WORDPRESS_API_URL');
133
+ return {
134
+ mode: 'error',
135
+ authMode: 'error',
136
+ dataSource: 'static',
137
+ baseUrl: '',
138
+ headers: {},
139
+ description: 'Invalid configuration - missing WordPress API URL',
140
+ suiteCRM: {
141
+ url: undefined,
142
+ proxyUrl: undefined,
143
+ appId: undefined,
144
+ workerSecret: undefined,
145
+ oauth2: {
146
+ clientId: undefined,
147
+ clientSecret: undefined,
148
+ tokenUrl: undefined,
149
+ username: undefined,
150
+ password: undefined,
151
+ },
152
+ }
153
+ };
154
+ }
155
+ if (isDevEnvironment()) {
156
+ console.log('๐Ÿ” Using direct WordPress mode (legacy - for local development only)');
157
+ }
158
+ const localDev = getEnv('VITE_LOCAL_DEVELOPMENT') === 'true';
159
+ return {
160
+ mode: localDev ? 'local' : 'remote',
161
+ authMode: 'direct',
162
+ dataSource: 'hybrid',
163
+ baseUrl: wpApiUrl,
164
+ headers: { 'Content-Type': 'application/json' },
165
+ description: localDev ? 'Direct (local dev) without Access' : 'Direct mode',
166
+ mautic: { url: getEnv('VITE_MAUTIC_URL') },
167
+ suiteCRM: {
168
+ url: getEnv('VITE_SUITECRM_URL'),
169
+ proxyUrl: getEnv('VITE_SUITECRM_PROXY_URL'),
170
+ appId: undefined,
171
+ workerSecret: undefined,
172
+ oauth2: {
173
+ clientId: getEnv('VITE_SUITECRM_CLIENT_ID'),
174
+ clientSecret: getEnv('VITE_SUITECRM_CLIENT_SECRET'),
175
+ tokenUrl: getEnv('VITE_SUITECRM_TOKEN_URL'),
176
+ username: getEnv('VITE_SUITECRM_USERNAME'),
177
+ password: getEnv('VITE_SUITECRM_PASSWORD'),
178
+ },
179
+ }
180
+ };
181
+ }
182
+ // This should never be reached, but just in case
183
+ return {
184
+ mode: 'error',
185
+ authMode: 'error',
186
+ dataSource: 'static',
187
+ baseUrl: '',
188
+ headers: {},
189
+ description: 'Invalid configuration - unknown error',
190
+ suiteCRM: {
191
+ url: undefined,
192
+ proxyUrl: undefined,
193
+ appId: undefined,
194
+ workerSecret: undefined,
195
+ oauth2: {
196
+ clientId: undefined,
197
+ clientSecret: undefined,
198
+ tokenUrl: undefined,
199
+ username: undefined,
200
+ password: undefined,
201
+ },
202
+ }
203
+ };
204
+ };
205
+ // Environment status and diagnostics
206
+ const getEnvironmentStatus = () => {
207
+ const config = getEnvironmentConfig();
208
+ const isLocal = isLocalDevelopment();
209
+ const authMode = getEnv('VITE_AUTH_MODE');
210
+ // Check if required credentials are available for each mode
211
+ const hasCloudflareCredentials = !!getEnv('VITE_CLOUDFLARE_WORKER_URL');
212
+ const hasWordPressApiUrl = !!getEnv('VITE_WORDPRESS_API_URL');
213
+ return {
214
+ currentConfig: config,
215
+ diagnostics: {
216
+ isLocalDevelopment: isLocal,
217
+ authMode: authMode,
218
+ hasCloudflareCredentials,
219
+ hasWordpressApiUrl: hasWordPressApiUrl,
220
+ cloudflareWorkerUrl: !!getEnv('VITE_CLOUDFLARE_WORKER_URL'),
221
+ cfAccessId: !!getEnv('VITE_CF_ACCESS_CLIENT_ID'),
222
+ cfAccessSecret: !!getEnv('VITE_CF_ACCESS_CLIENT_SECRET'),
223
+ mauticProxyUrl: !!getEnv('VITE_MAUTIC_PROXY_URL')
224
+ },
225
+ recommendations: {
226
+ // Only show recommendation if authMode is explicitly set to an invalid value
227
+ // Default is cloudflare_proxy, so no recommendation needed if not set
228
+ authMode: null, // Defaults to cloudflare_proxy, no warning needed
229
+ cloudflare: null // Pages Functions work without explicit worker URL
230
+ }
231
+ };
232
+ };
233
+ // Export current environment config as default
234
+ getEnvironmentConfig();
235
+ getEnvironmentStatus();
236
+
237
+ const MauticTracking = ({ enabled, mauticUrl, proxyUrl }) => {
238
+ // Get configuration from environment config
239
+ const envConfig = getEnvironmentConfig();
240
+ const isEnabled = enabled ?? (envConfig.authMode === 'cloudflare_proxy' && !!envConfig.mautic?.proxyUrl);
241
+ const trackingUrl = mauticUrl ?? envConfig.mautic?.url;
242
+ const trackingProxyUrl = proxyUrl ?? envConfig.mautic?.proxyUrl;
243
+ // Use the package component
244
+ return (jsx(MauticTracking$1, { enabled: isEnabled, mauticUrl: trackingUrl, proxyUrl: trackingProxyUrl }));
245
+ };
246
+
247
+ // @ts-nocheck
248
+ const ChatwootWidget = forwardRef(({ config, enabled = true, className, }, ref) => {
249
+ const scriptLoaded = useRef(false);
250
+ const widgetInitialized = useRef(false);
251
+ useEffect(() => {
252
+ if (!enabled || scriptLoaded.current)
253
+ return;
254
+ // Load Chatwoot script
255
+ const script = document.createElement('script');
256
+ script.src = `${config.baseUrl || 'https://app.chatwoot.com'}/packs/js/sdk.js`;
257
+ script.async = true;
258
+ script.defer = true;
259
+ script.onload = () => {
260
+ scriptLoaded.current = true;
261
+ initializeWidget();
262
+ };
263
+ document.head.appendChild(script);
264
+ return () => {
265
+ // Cleanup script if component unmounts before loading
266
+ if (document.head.contains(script)) {
267
+ document.head.removeChild(script);
268
+ }
269
+ };
270
+ }, [enabled, config.baseUrl]);
271
+ useEffect(() => {
272
+ if (scriptLoaded.current && !widgetInitialized.current) {
273
+ initializeWidget();
274
+ }
275
+ }, [config]);
276
+ const initializeWidget = () => {
277
+ if (widgetInitialized.current || !window.chatwootSDK)
278
+ return;
279
+ // Set global settings
280
+ window.chatwootSettings = {
281
+ hideMessageBubble: config.hideMessageBubble,
282
+ position: config.position,
283
+ locale: config.locale,
284
+ type: config.type,
285
+ launcherTitle: config.launcherTitle,
286
+ showPopoutButton: config.showPopoutButton,
287
+ };
288
+ // Initialize the widget
289
+ window.chatwootSDK.run({
290
+ websiteToken: config.websiteToken,
291
+ baseUrl: config.baseUrl || 'https://app.chatwoot.com',
292
+ });
293
+ widgetInitialized.current = true;
294
+ };
295
+ // Expose widget controls
296
+ React.useImperativeHandle(ref, () => ({
297
+ toggle: () => window.chatwootSDK?.toggle(),
298
+ show: () => window.chatwootSDK?.show(),
299
+ hide: () => window.chatwootSDK?.hide(),
300
+ reset: () => window.chatwootSDK?.reset(),
301
+ }));
302
+ // Don't render anything in the DOM - Chatwoot creates its own elements
303
+ return null;
304
+ });
305
+ ChatwootWidget.displayName = 'ChatwootWidget';
306
+
307
+ export { ChatwootWidget, MauticTracking };
308
+ //# sourceMappingURL=integrations.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integrations.esm.js","sources":["../src/runtime/env.ts","../src/config/environment.ts","../src/components/integrations/mautic-tracking.tsx","../src/components/integrations/chatwoot-widget.tsx"],"sourcesContent":[null,null,null,null],"names":["_jsx","MauticTrackingComponent"],"mappings":"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"}
@@ -18,13 +18,25 @@ The command **creates or updates** `.env.example` and `.env.local.example`. The
18
18
 
19
19
  **`VITE_IS_LOVABLE` (generators only):** Used in hosted Lovable/CI โ€œfixtureโ€ flows to skip live API fetches. **Do not set this in local full-data development.** See [SEO-PERFORMANCE.md](./SEO-PERFORMANCE.md) and your appโ€™s `DIGIVALT_SETUP.md`. It is **not** part of the managed example block; it is listed in `deploy-secrets` excluded keys (below).
20
20
 
21
+ ## React 19 install (consumer apps)
22
+
23
+ `@marvalt/digivalt-core` peers **`react-helmet-async`** for SEO (`@marvalt/digivalt-core/seo`). That package currently declares peer support for React 16โ€“18 only. If your app uses **React 19**, npm may fail with `ERESOLVE`:
24
+
25
+ **Fix:** add a project **`.npmrc`** file:
26
+
27
+ ```ini
28
+ legacy-peer-deps=true
29
+ ```
30
+
31
+ Or install once with `npm install --legacy-peer-deps`. Runtime behavior with React 19 is fine; this is an npm peer-range mismatch until upstream updates.
32
+
21
33
  ## Handover to DevOps (Cloudflare and secrets)
22
34
 
23
35
  ### `node scripts/deploy-secrets.js`
24
36
 
25
37
  After `digivalt-init`, the app has [`scripts/deploy-secrets.js`](../template/scripts/deploy-secrets.js) (from the template). It reads **`.env`** and **`.env.local`**, then uploads only keys that pass an **allowlist** to Cloudflare Pages via Wrangler `pages secret bulk`.
26
38
 
27
- - **Allowlist (summary):** patterns include `CLOUDFLARE_*`, `CF_ACCESS_*`, `TURNSTILE_*`, `VITE_SEO_*`, and `VITE_`-prefixed keys for WordPress, Gravity Forms, Mautic, SuiteCRM, Supabase, Cloudflare worker URL, auth, Turnstile, Chatwoot, theme, and similar integrations (see the `allowedPatterns` array in the script).
39
+ - **Allowlist (summary):** all **`VITE_*`** keys except **`VITE_IS_LOVABLE`**, **`VITE_LOCAL_DEVELOPMENT`**, **`VITE_AUTH_MODE`**, **`VITE_DEFAULT_MAX_ITEMS`**; plus **`CLOUDFLARE_*`**, **`CF_ACCESS_*`**, **`TURNSTILE_*`**, **`ALLOWED_ORIGINS`**, **`SITE_URL`**, and Node alias prefixes **`WORDPRESS_`**, **`WP_`**, **`GF_`**, **`GRAVITY_FORMS_`**, **`MAUTIC_`**, **`SUITECRM_`**, **`GOOGLE_REVIEWS_`**. **`NPM_TOKEN`** is never uploaded. Run **`node scripts/deploy-secrets.js --dry-run`** to list keys before upload.
28
40
  - **Excluded from bulk upload (set in the Pages UI or locally instead):** `NODE_ENV`, `VITE_IS_LOVABLE`, `VITE_LOCAL_DEVELOPMENT`, `VITE_AUTH_MODE`, `VITE_DEFAULT_MAX_ITEMS` โ€” so environment-specific or non-secret toggles are not mass-synced.
29
41
  - **Empty values** are skipped. **`CLOUDFLARE_ACCOUNT_ID`** in env is used when invoking Wrangler; the **project name** comes from **`wrangler.toml`** in the app root.
30
42
  - **Turnstile:** `VITE_TURNSTILE_SITE_KEY` is for the browser; **`TURNSTILE_SECRET_KEY`** is server-only for Pages Functions (not a `VITE_` var). Both can appear in the allowlist path when set in your env files.
@@ -41,9 +53,20 @@ Align **`name`** in `wrangler.toml` with your **Cloudflare Pages** project. Loca
41
53
  | **Theme** | `VITE_THEME` โ€” optional; see `loadTheme` in `config/themes`. |
42
54
  | **Integrations (URLs often public; secrets in `.env.local`)** | Mautic, SuiteCRM, Supabase, Chatwoot, Gravity Forms โ€” see `getIntegrationConfig` in `src/config/integrations.ts`. `VITE_SUITECRM_TOKEN_URL` is optional for non-default OAuth token endpoints (`environment.ts`). |
43
55
  | **SEO** | `VITE_SEO_*` โ€” see [SEO-PERFORMANCE.md](./SEO-PERFORMANCE.md) and `getSEOConfig`. |
56
+ | **Analytics** | `VITE_GA_TRACKING_CODE`, `VITE_MATOMO_TRACKING_CODE`, `VITE_TRACKING_IN_DEV` โ€” mount **`DigiValtTracker`** from **`@marvalt/digivalt-core/integrations`** (depends on **`@digivalt/tracker`**). See `node_modules/@digivalt/tracker/docs/ENVIRONMENT.md`. |
44
57
  | **Performance** | `VITE_PERF_*` โ€” optional toggles; see [SEO-PERFORMANCE.md](./SEO-PERFORMANCE.md) and `getPerformanceConfig`. |
45
58
  | **Secrets (typical in `.env.local`)** | WordPress app password, Cloudflare Access, Mautic API keys, GF keys, SuiteCRM creds, `VITE_FRONTEND_SECRET` / `VITE_WP_REFRESH_SECRET` (webhook), `VITE_TURNSTILE_SITE_KEY` + `TURNSTILE_SECRET_KEY`. |
46
59
 
60
+ ## Browser integrations (`/integrations`)
61
+
62
+ Import from **`@marvalt/digivalt-core/integrations`** (published in npm `dist/`):
63
+
64
+ - `DigiValtTracker` โ€” GA / Matomo snippets (`@digivalt/tracker`)
65
+ - `MauticTracking` โ€” Mautic page tracking
66
+ - `ChatwootWidget` โ€” Chatwoot embed
67
+
68
+ Do **not** import shadcn-dependent forms, `wpRegistry`, or popups from npm dist โ€” those live in package **source** for `digivalt-init` apps with `@/` โ†’ `src/components/ui`.
69
+
47
70
  ## Further reading
48
71
 
49
72
  - [SEO-PERFORMANCE.md](./SEO-PERFORMANCE.md) โ€” `VITE_SEO_*`, `VITE_PERF_*`, sitemap, Lovable / `VITE_IS_LOVABLE` behavior
package/docs/README.md ADDED
@@ -0,0 +1,38 @@
1
+ # @marvalt/digivalt-core documentation
2
+
3
+ Read these in order for DigiValt app setup, deploy, and SEO.
4
+
5
+ | Doc | Audience | Purpose |
6
+ |-----|----------|---------|
7
+ | [ENVIRONMENT.md](./ENVIRONMENT.md) | Devs + DevOps | Env vars, `.env` model, Cloudflare secrets, React 19 install |
8
+ | [AI-LOCAL-WORDPRESS-BOOTSTRAP.md](./AI-LOCAL-WORDPRESS-BOOTSTRAP.md) | Humans | Local WordPress handover runbook |
9
+ | [LOVABLE-MASTER-PROMPT.md](./LOVABLE-MASTER-PROMPT.md) | AI tools | Tool-agnostic scaffold prompt |
10
+ | [SEO-PERFORMANCE.md](./SEO-PERFORMANCE.md) | Devs | `DigiValtSeoHead`, sitemap, `VITE_SEO_*`, performance |
11
+
12
+ Package root [README.md](../README.md) covers `digivalt-init`, generators, and entry points.
13
+
14
+ ## Package entry points (npm)
15
+
16
+ | Subpath | Use |
17
+ |---------|-----|
18
+ | `@marvalt/digivalt-core/generators` | Build-time static data (`generateAllData`) |
19
+ | `@marvalt/digivalt-core/seo` | `DigiValtSeoHead`, JSON-LD helpers |
20
+ | `@marvalt/digivalt-core/integrations` | Browser-only: `DigiValtTracker`, `MauticTracking`, `ChatwootWidget` |
21
+ | `@marvalt/digivalt-core/config` | Integration config from env |
22
+ | `@marvalt/digivalt-core/static` | Load generated JSON at runtime |
23
+
24
+ Shadcn-heavy UI in package **source** (forms, `wpRegistry`, etc.) is **not** in published `dist/` โ€” apps wire those via `digivalt-init` and local `@/` โ†’ `src/components/ui` aliases.
25
+
26
+ ## Adapter packages (installed as dependencies)
27
+
28
+ Each ships its own `docs/README.md` under `node_modules/@marvalt/<package>/docs/`:
29
+
30
+ - `@marvalt/wadapter` โ€” WordPress + Gravity Forms
31
+ - `@marvalt/madapter` โ€” Mautic
32
+ - `@marvalt/wparser` โ€” Gutenberg block rendering
33
+ - `@marvalt/dstyler` โ€” Theme / section styling
34
+ - `@marvalt/shcoder` โ€” CPT shortcode components
35
+ - `@marvalt/tadapter` โ€” Testimonial submission
36
+ - `@marvalt/sadapter` โ€” SuiteCRM
37
+ - `@marvalt/cadapter` โ€” Calendly embeds
38
+ - `@digivalt/tracker` โ€” Google Analytics + Matomo (required dependency; import via **`@marvalt/digivalt-core/integrations`**)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marvalt/digivalt-core",
3
- "version": "0.2.16",
3
+ "version": "0.2.21",
4
4
  "description": "Core glue logic and shared context for DigiVAlt frontend applications",
5
5
  "license": "GPL-3.0-or-later",
6
6
  "main": "dist/index.cjs",
@@ -41,6 +41,11 @@
41
41
  "types": "./dist/seo.d.ts",
42
42
  "import": "./dist/seo.esm.js",
43
43
  "require": "./dist/seo.cjs"
44
+ },
45
+ "./integrations": {
46
+ "types": "./dist/integrations.d.ts",
47
+ "import": "./dist/integrations.esm.js",
48
+ "require": "./dist/integrations.cjs"
44
49
  }
45
50
  },
46
51
  "bin": {
@@ -68,11 +73,9 @@
68
73
  "smoke:sitemap": "node ./scripts/test-sitemap-paths.cjs",
69
74
  "smoke:google-reviews-gate": "node ./scripts/test-google-reviews-gate.cjs",
70
75
  "smoke": "npm run smoke:imports && npm run smoke:init && npm run smoke:sitemap && npm run smoke:google-reviews-gate",
71
- "prepublishOnly": "npm run clean && npm run build && npm run smoke"
76
+ "prepublishOnly": "npm run clean && npm run build && npm run smoke && node ../scripts/verify-pack.cjs"
72
77
  },
73
78
  "devDependencies": {
74
- "react": "^18.3.1",
75
- "react-dom": "^18.3.1",
76
79
  "@rollup/plugin-commonjs": "^25.0.7",
77
80
  "@rollup/plugin-json": "^6.1.0",
78
81
  "@rollup/plugin-node-resolve": "^15.2.3",
@@ -80,7 +83,11 @@
80
83
  "@types/node": "^22.5.5",
81
84
  "@types/react": "^18.3.3",
82
85
  "@types/react-dom": "^18.3.0",
86
+ "@tanstack/react-query": "^5.62.0",
87
+ "react": "^18.3.1",
88
+ "react-dom": "^18.3.1",
83
89
  "react-helmet-async": "^2.0.5",
90
+ "react-router-dom": "^6.28.0",
84
91
  "rimraf": "^5.0.5",
85
92
  "rollup": "^4.6.1",
86
93
  "rollup-plugin-dts": "^6.1.0",
@@ -97,6 +104,7 @@
97
104
  "npm": ">=8.0.0"
98
105
  },
99
106
  "dependencies": {
107
+ "@digivalt/tracker": "^0.1.0",
100
108
  "@marvalt/dstyler": "^0.1.51",
101
109
  "@marvalt/madapter": "^2.3.7",
102
110
  "@marvalt/sadapter": "^0.1.5",
@@ -87,4 +87,23 @@ Init will:
87
87
  4. **Sitemap:** **`/sitemap.xml`** is served by **`functions/sitemap.xml.ts`**. **`public/sitemap-paths.json`** is **generated** when you run **`npm run build`** (or `generate`): it merges (a) **`public/sitemap-static-paths.json`** โ€” edit this for Lovable/SPA-only routes, (b) URLs from **`navigation_menu`** in **`wordpress-data.json`**, (c) **`link`** pathnames from CPT/post arrays listed under **`config.post_types`**. Only CMS links whose host matches **`VITE_WORDPRESS_API_URL`** / **`WORDPRESS_API_URL`** are included. Canonical `<loc>` values use **`VITE_SEO_SITE_URL`** (or **`SITE_URL`**). Do not add **`public/sitemap.xml`** (it would shadow the Function). With **`VITE_IS_LOVABLE=true`**, static fetch is skipped but sitemap paths are still regenerated from committed JSON.
88
88
  5. Read the full guide shipped with the package: **`node_modules/@marvalt/digivalt-core/docs/SEO-PERFORMANCE.md`** (or in the repo: `digivalt-npm-packages/digivalt-core/docs/SEO-PERFORMANCE.md`).
89
89
 
90
+ ## 8. Analytics (Google Analytics / Matomo)
91
+
92
+ `@marvalt/digivalt-core` depends on **`@digivalt/tracker`**. Paste each platformโ€™s full tracking snippet into env vars (see **`node_modules/@digivalt/tracker/docs/ENVIRONMENT.md`**):
93
+
94
+ - `VITE_GA_TRACKING_CODE` โ€” Google Analytics gtag snippet
95
+ - `VITE_MATOMO_TRACKING_CODE` โ€” Matomo snippet
96
+ - `VITE_TRACKING_IN_DEV` โ€” optional; set `true` to enable in local dev
97
+
98
+ Mount inside **`BrowserRouter`**:
99
+
100
+ ```tsx
101
+ import { DigiValtTracker } from '@marvalt/digivalt-core/integrations';
102
+
103
+ <BrowserRouter>
104
+ <DigiValtTracker />
105
+ <Routes>...</Routes>
106
+ </BrowserRouter>
107
+ ```
108
+
90
109
  You are fully onboarded and ready to develop offline!
@@ -3,31 +3,45 @@ import path from 'path';
3
3
  import { execSync } from 'child_process';
4
4
 
5
5
  /**
6
- * ๐Ÿš€ DigiVAlt Cloudflare Secrets Deployer
7
- *
8
- * Automates the synchronization of local .env.local variables
9
- * securely straight into your Cloudflare Pages environment
10
- * using Wrangler bulk secret injection.
6
+ * DigiValt Cloudflare Pages secrets deployer
7
+ *
8
+ * Reads .env and .env.local, uploads allowed keys via wrangler pages secret bulk.
9
+ * Run: node scripts/deploy-secrets.js
10
+ * Dry run: node scripts/deploy-secrets.js --dry-run
11
11
  */
12
12
 
13
+ const dryRun = process.argv.includes('--dry-run');
14
+
13
15
  const secrets = {};
14
- /** Keys we never push from .env / .env.local (local dev or set manually on Cloudflare Pages). */
16
+
17
+ /** Local-only or non-Pages keys โ€” never bulk-uploaded. */
15
18
  const excludedKeys = new Set([
16
19
  'NODE_ENV',
20
+ 'NPM_TOKEN',
17
21
  'VITE_IS_LOVABLE',
18
22
  'VITE_LOCAL_DEVELOPMENT',
19
23
  'VITE_AUTH_MODE',
20
24
  'VITE_DEFAULT_MAX_ITEMS',
21
25
  ]);
22
26
 
23
- // VITE_SEO_* are often public (verification meta, titles); allow upload when teams store them as Pages secrets.
24
- // TURNSTILE_SECRET_KEY is server-only (Pages Functions), not a VITE_ prefix.
27
+ /**
28
+ * Allow DigiValt build/runtime variables (see digivalt-core bin/env-example-fragments.cjs).
29
+ * All VITE_* except excludedKeys; plus Node/generator alias names without VITE_ prefix.
30
+ */
25
31
  const allowedPatterns = [
26
32
  /^CLOUDFLARE_/,
27
33
  /^CF_ACCESS_/,
28
34
  /^TURNSTILE_/,
29
- /^VITE_SEO_/,
30
- /^VITE_(WORDPRESS|WP|GF|GRAVITY_FORMS|FRONTEND|FRONTENDS|MAUTIC|SUITECRM|SUPABASE|CLOUDFLARE|AUTH|TURNSTILE|CHATWOOT|THEME|GOOGLE_|FACEBOOK_|LINKEDIN_)/,
35
+ /^ALLOWED_ORIGINS$/,
36
+ /^SITE_URL$/,
37
+ /^WORDPRESS_/,
38
+ /^WP_/,
39
+ /^GF_/,
40
+ /^GRAVITY_FORMS_/,
41
+ /^MAUTIC_/,
42
+ /^SUITECRM_/,
43
+ /^GOOGLE_REVIEWS_/,
44
+ /^VITE_/,
31
45
  ];
32
46
 
33
47
  const isAllowedSecretKey = (key) => allowedPatterns.some((pattern) => pattern.test(key));
@@ -35,7 +49,7 @@ const isAllowedSecretKey = (key) => allowedPatterns.some((pattern) => pattern.te
35
49
  const parseEnvFile = (filePath) => {
36
50
  if (!fs.existsSync(filePath)) return;
37
51
 
38
- console.log(`๐Ÿ” Parsing ${path.basename(filePath)} secrets...`);
52
+ console.log(`๐Ÿ” Parsing ${path.basename(filePath)}...`);
39
53
  const rawEnv = fs.readFileSync(filePath, 'utf8');
40
54
 
41
55
  rawEnv.split('\n').forEach((line) => {
@@ -49,12 +63,12 @@ const parseEnvFile = (filePath) => {
49
63
  let value = match[2].trim();
50
64
 
51
65
  if (excludedKeys.has(key)) {
52
- console.log(`โš ๏ธ Skipping ${key} (DigiVAlt: excluded from Cloudflare bulk upload)`);
66
+ console.log(`โš ๏ธ Skipping ${key} (excluded from Cloudflare bulk upload)`);
53
67
  return;
54
68
  }
55
69
 
56
70
  if (!isAllowedSecretKey(key)) {
57
- console.log(`โš ๏ธ Skipping ${key} (not in DigiVAlt allowlist)`);
71
+ console.log(`โš ๏ธ Skipping ${key} (not in DigiValt allowlist)`);
58
72
  return;
59
73
  }
60
74
 
@@ -78,57 +92,57 @@ parseEnvFile(localEnvPath);
78
92
 
79
93
  const secretCount = Object.keys(secrets).length;
80
94
  if (secretCount === 0) {
81
- console.error('โŒ No allowed DigiVAlt environment variables were found in .env or .env.local.');
95
+ console.error('โŒ No allowed environment variables were found in .env or .env.local.');
82
96
  process.exit(1);
83
97
  }
84
98
 
99
+ console.log(`๐Ÿ“‹ ${secretCount} key(s) ready: ${Object.keys(secrets).sort().join(', ')}`);
100
+
101
+ if (dryRun) {
102
+ console.log('โœ… Dry run complete (nothing uploaded).');
103
+ process.exit(0);
104
+ }
105
+
85
106
  const tmpJsonPath = path.resolve(process.cwd(), '.tmp-cloudflare-secrets.json');
86
107
  fs.writeFileSync(tmpJsonPath, JSON.stringify(secrets, null, 2));
87
108
 
88
109
  try {
89
110
  console.log(`๐Ÿš€ Uploading ${secretCount} secrets to Cloudflare Pages...`);
90
-
91
- // Extract Cloudflare Account ID directly from the parsed environment variables!
111
+
92
112
  const accountId = secrets['CLOUDFLARE_ACCOUNT_ID'] || secrets['VITE_CLOUDFLARE_ACCOUNT_ID'] || '';
93
-
94
- // Try to read the Cloudflare project name from wrangler.toml
113
+
95
114
  const tomlPath = path.resolve(process.cwd(), 'wrangler.toml');
96
115
  let projectName = '';
97
-
116
+
98
117
  if (fs.existsSync(tomlPath)) {
99
118
  const tomlContent = fs.readFileSync(tomlPath, 'utf8');
100
-
101
- // Parse Project Name
102
119
  const nameMatch = tomlContent.match(/^name\s*=\s*["']([^"']+)["']/m);
103
120
  if (nameMatch) projectName = nameMatch[1];
104
-
105
- if (projectName) console.log(`๐Ÿ“ฆ Targeted Cloudflare Project: ${projectName}`);
106
- if (accountId) console.log(`๐Ÿข Targeted Cloudflare Account: ${accountId}`);
121
+
122
+ if (projectName) console.log(`๐Ÿ“ฆ Target Cloudflare project: ${projectName}`);
123
+ if (accountId) console.log(`๐Ÿข Target Cloudflare account: ${accountId}`);
107
124
  }
108
-
125
+
109
126
  if (!projectName) {
110
127
  throw new Error('Could not determine the Cloudflare Pages project name from wrangler.toml.');
111
128
  }
112
129
 
113
130
  let cmd = `npx wrangler pages secret bulk .tmp-cloudflare-secrets.json`;
114
131
  cmd += ` --project-name ${projectName}`;
115
-
116
- // Execute Wrangler natively with the Account ID passed through the strict environment scope
132
+
117
133
  const env = { ...process.env };
118
134
  if (accountId) {
119
135
  env.CLOUDFLARE_ACCOUNT_ID = accountId;
120
136
  }
121
-
137
+
122
138
  execSync(cmd, { stdio: 'inherit', env });
123
139
  console.log('โœ… All secrets deployed successfully to Cloudflare!');
124
-
125
140
  } catch (error) {
126
141
  console.error('โŒ Failed to push secrets to Cloudflare.');
127
142
  console.error('Ensure you are logged into Wrangler (`npx wrangler login`) and the project exists.');
128
143
  console.error(error instanceof Error ? error.message : error);
129
144
  process.exitCode = 1;
130
145
  } finally {
131
- // Always rigorously clean up the temporary plaintext JSON file for security
132
146
  if (fs.existsSync(tmpJsonPath)) {
133
147
  fs.unlinkSync(tmpJsonPath);
134
148
  console.log('๐Ÿงน Cleaned up temporary credentials payload.');