@marvalt/digivalt-core 0.1.7 → 0.2.0

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.
Files changed (44) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +32 -4
  3. package/bin/init.cjs +42 -7
  4. package/dist/config.cjs +520 -0
  5. package/dist/config.cjs.map +1 -0
  6. package/dist/config.d.ts +307 -0
  7. package/dist/config.esm.js +502 -0
  8. package/dist/config.esm.js.map +1 -0
  9. package/dist/generators.cjs +2481 -0
  10. package/dist/generators.cjs.map +1 -0
  11. package/dist/generators.d.ts +19 -0
  12. package/dist/generators.esm.js +2475 -0
  13. package/dist/generators.esm.js.map +1 -0
  14. package/dist/index.cjs +18 -7955
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d.ts +18 -1196
  17. package/dist/index.esm.js +13 -7929
  18. package/dist/index.esm.js.map +1 -1
  19. package/dist/runtime/env.d.ts +4 -0
  20. package/dist/runtime/lazy.d.ts +1 -0
  21. package/dist/services/cf-wp-webhook.d.ts +2 -0
  22. package/dist/services/gravityForms.d.ts +3 -0
  23. package/dist/services/mautic.d.ts +5 -1
  24. package/dist/services/suitecrm.d.ts +2 -0
  25. package/dist/services.cjs +1339 -0
  26. package/dist/services.cjs.map +1 -0
  27. package/dist/services.d.ts +432 -0
  28. package/dist/services.esm.js +1322 -0
  29. package/dist/services.esm.js.map +1 -0
  30. package/dist/static/index.d.ts +4 -0
  31. package/dist/static.cjs +997 -0
  32. package/dist/static.cjs.map +1 -0
  33. package/dist/static.d.ts +410 -0
  34. package/dist/static.esm.js +962 -0
  35. package/dist/static.esm.js.map +1 -0
  36. package/dist/types.cjs +3 -0
  37. package/dist/types.cjs.map +1 -0
  38. package/dist/types.d.ts +134 -0
  39. package/dist/types.esm.js +2 -0
  40. package/dist/types.esm.js.map +1 -0
  41. package/package.json +30 -2
  42. package/template/DIGIVALT_SETUP.md +62 -0
  43. package/template/scripts/deploy-secrets.js +55 -23
  44. package/template/scripts/generate.ts +3 -17
package/CHANGELOG.md CHANGED
@@ -5,6 +5,19 @@ 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.0] - 2026-02-19
9
+
10
+ ### Changed
11
+ - Added explicit subpath exports for `generators`, `services`, `config`, `static`, and `types`.
12
+ - Reduced the root package entry to a thin compatibility surface for generator-oriented consumers.
13
+ - Converted Gravity Forms, Mautic, and webhook service initialization to lazy creation instead of import-time setup.
14
+ - Removed automatic Gravity Forms static-data loading on import.
15
+ - Hardened `digivalt-init` with target validation and dry-run support.
16
+ - Hardened Cloudflare secret deployment with an allowlist and fail-loud behavior.
17
+
18
+ ### Migration Notes
19
+ - Prefer `@marvalt/digivalt-core/generators` in build-time scripts instead of importing `generators` from the root entry.
20
+
8
21
  ## [0.1.0] - Initial Release
9
22
 
10
23
  ### Added
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @marvalt/digivalt-core
2
2
 
3
- Core logic and shared context for DigiVAlt frontend applications.
3
+ Core DigiVAlt package for static data generation, runtime service wiring, and Cloudflare Pages bootstrap helpers.
4
4
 
5
5
  ## Installation
6
6
 
@@ -8,6 +8,34 @@ Core logic and shared context for DigiVAlt frontend applications.
8
8
  npm install @marvalt/digivalt-core
9
9
  ```
10
10
 
11
- ## Overview
12
- This package contains the shared "glue" code that unifies WordPress headless configurations, Mautic connections, Cloudflare setup, and form integrations for DigiValt static-first applications.
13
- It makes it easy to convert any standard React/Vite app into a full DigiVAlt implementation.
11
+ ## Entry Points
12
+
13
+ Prefer explicit subpath imports so Node/build-time code does not pull browser runtime modules:
14
+
15
+ ```ts
16
+ import { generateAllData } from '@marvalt/digivalt-core/generators';
17
+ import { getIntegrationConfig } from '@marvalt/digivalt-core/config';
18
+ import { loadWordPressData } from '@marvalt/digivalt-core/static';
19
+ import { gravityFormsService } from '@marvalt/digivalt-core/services';
20
+ ```
21
+
22
+ The root package export remains as a thin compatibility layer for generator-focused consumers.
23
+
24
+ ## Init Workflow
25
+
26
+ Run `npx digivalt-init` inside a Vite/Lovable app root. The command now validates the target folder before copying templates.
27
+
28
+ Useful flags:
29
+
30
+ - `--target <path>` to initialize a different app folder
31
+ - `--dry-run` to preview copied files without writing anything
32
+
33
+ ## Cloudflare Secrets
34
+
35
+ Use `node scripts/deploy-secrets.js` after `digivalt-init`.
36
+
37
+ The helper now:
38
+
39
+ - uploads only DigiVAlt-related environment variables
40
+ - skips known local-only variables such as `VITE_LOCAL_DEVELOPMENT`
41
+ - fails with a non-zero exit code when Wrangler or project detection fails
package/bin/init.cjs CHANGED
@@ -4,9 +4,40 @@ const fs = require('fs');
4
4
  const path = require('path');
5
5
 
6
6
  const sourceDir = path.join(__dirname, '..', 'template');
7
- const targetDir = process.cwd();
7
+ const args = process.argv.slice(2);
8
+
9
+ function getArgValue(flag) {
10
+ const index = args.indexOf(flag);
11
+ return index >= 0 ? args[index + 1] : undefined;
12
+ }
13
+
14
+ const dryRun = args.includes('--dry-run');
15
+ const explicitTarget = getArgValue('--target');
16
+ const targetDir = path.resolve(explicitTarget || process.cwd());
8
17
 
9
18
  console.log('🚀 Initializing DigiVAlt Cloudflare Proxy Templates...');
19
+ console.log(`📁 Target directory: ${targetDir}`);
20
+ if (dryRun) {
21
+ console.log('🧪 Dry run enabled. No files will be written.');
22
+ }
23
+
24
+ function ensureValidTarget(dir) {
25
+ if (!fs.existsSync(dir)) {
26
+ throw new Error(`Target directory does not exist: ${dir}`);
27
+ }
28
+
29
+ const stats = fs.statSync(dir);
30
+ if (!stats.isDirectory()) {
31
+ throw new Error(`Target path is not a directory: ${dir}`);
32
+ }
33
+
34
+ const packageJsonPath = path.join(dir, 'package.json');
35
+ if (!fs.existsSync(packageJsonPath)) {
36
+ throw new Error(
37
+ 'No package.json found in the target directory. Run `digivalt-init` inside a Vite/Lovable app root, or pass `--target <app-path>`.'
38
+ );
39
+ }
40
+ }
10
41
 
11
42
  function copyRecursiveSync(src, dest) {
12
43
  const exists = fs.existsSync(src);
@@ -14,7 +45,7 @@ function copyRecursiveSync(src, dest) {
14
45
  const isDirectory = exists && stats.isDirectory();
15
46
 
16
47
  if (isDirectory) {
17
- if (!fs.existsSync(dest)) fs.mkdirSync(dest);
48
+ if (!fs.existsSync(dest) && !dryRun) fs.mkdirSync(dest, { recursive: true });
18
49
  fs.readdirSync(src).forEach((childItemName) => {
19
50
  copyRecursiveSync(path.join(src, childItemName), path.join(dest, childItemName));
20
51
  });
@@ -23,20 +54,24 @@ function copyRecursiveSync(src, dest) {
23
54
  if (fs.existsSync(dest)) {
24
55
  console.log(`⚠️ Skipping ${dest.replace(targetDir, '')} (Already exists)`);
25
56
  } else {
26
- fs.copyFileSync(src, dest);
27
- console.log(`✅ Copied ${dest.replace(targetDir, '')}`);
57
+ if (!dryRun) {
58
+ fs.copyFileSync(src, dest);
59
+ }
60
+ console.log(`✅ ${dryRun ? 'Would copy' : 'Copied'} ${dest.replace(targetDir, '')}`);
28
61
  }
29
62
  }
30
63
  }
31
64
 
32
65
  try {
66
+ ensureValidTarget(targetDir);
33
67
  copyRecursiveSync(sourceDir, targetDir);
34
68
  console.log('\n🎉 DigiVAlt Cloudflare proxy routes installed successfully!');
35
69
  console.log('👉 Next Steps:');
36
70
  console.log('1. Copy .dev.vars.example to .dev.vars and add your API keys.');
37
- console.log("2. Sync your production credentials to Cloudflare by running:");
38
- console.log(" 👉 node scripts/deploy-secrets.js");
39
- console.log("3. Run `npx wrangler pages dev` to test your proxy functions locally.");
71
+ console.log('2. Review `wrangler.toml` and confirm the Pages project name matches your app.');
72
+ console.log('3. Sync your production credentials to Cloudflare by running:');
73
+ console.log(' 👉 node scripts/deploy-secrets.js');
74
+ console.log('4. Run `npx wrangler pages dev` to test your proxy functions locally.');
40
75
  } catch (error) {
41
76
  console.error('❌ Failed to construct templates:', error);
42
77
  process.exit(1);
@@ -0,0 +1,520 @@
1
+ 'use strict';
2
+
3
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
4
+ const getImportMetaEnv = () => {
5
+ try {
6
+ return typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('config.cjs', document.baseURI).href)) }) !== 'undefined' ? undefined : undefined;
7
+ }
8
+ catch {
9
+ return undefined;
10
+ }
11
+ };
12
+ const getEnv = (key) => {
13
+ const viteEnv = getImportMetaEnv();
14
+ if (viteEnv && key in viteEnv) {
15
+ const value = viteEnv[key];
16
+ return value == null ? undefined : String(value);
17
+ }
18
+ if (typeof process !== 'undefined' && process.env && key in process.env) {
19
+ const value = process.env[key];
20
+ return value == null ? undefined : String(value);
21
+ }
22
+ return undefined;
23
+ };
24
+ const isDevEnvironment = () => {
25
+ const viteEnv = getImportMetaEnv();
26
+ if (viteEnv && 'DEV' in viteEnv) {
27
+ return Boolean(viteEnv.DEV);
28
+ }
29
+ return typeof process !== 'undefined' && process.env?.NODE_ENV === 'development';
30
+ };
31
+
32
+ // Detect if we're running in a local development environment
33
+ const isLocalDevelopment = () => {
34
+ // Check if we're in a browser environment
35
+ if (typeof window !== 'undefined') {
36
+ // Check for local development indicators
37
+ const isLocalhost = window.location.hostname === 'localhost' ||
38
+ window.location.hostname === '127.0.0.1' ||
39
+ window.location.hostname.includes('192.168.') ||
40
+ window.location.hostname.includes('10.0.');
41
+ const isDevPort = window.location.port === '3000' ||
42
+ window.location.port === '5173' ||
43
+ window.location.port === '8080';
44
+ const hasLocalEnv = Boolean(getEnv('DEV')) || getEnv('VITE_LOCAL_DEVELOPMENT') === 'true';
45
+ return Boolean(isLocalhost && (isDevPort || hasLocalEnv));
46
+ }
47
+ else {
48
+ // Node.js environment - check environment variables
49
+ return getEnv('NODE_ENV') === 'development' ||
50
+ getEnv('VITE_LOCAL_DEVELOPMENT') === 'true';
51
+ }
52
+ };
53
+ // Get the appropriate environment configuration
54
+ const getEnvironmentConfig = () => {
55
+ const isLocal = isLocalDevelopment();
56
+ // Default to cloudflare_proxy (via Cloudflare Pages Functions)
57
+ // Use 'direct' only for local development with whitelisted IPs
58
+ const authModeRaw = getEnv('VITE_AUTH_MODE');
59
+ const authMode = authModeRaw || 'cloudflare_proxy';
60
+ // Reduced debug logging - only in development and only once
61
+ if (isDevEnvironment() && !authModeRaw) {
62
+ console.log('ℹ️ VITE_AUTH_MODE not set, defaulting to cloudflare_proxy (Cloudflare Pages Functions)');
63
+ }
64
+ // Validate auth mode value
65
+ if (authMode !== 'direct' && authMode !== 'cloudflare_proxy') {
66
+ console.error('❌ Invalid VITE_AUTH_MODE value. Must be "direct" or "cloudflare_proxy".');
67
+ return {
68
+ mode: 'error',
69
+ authMode: 'error',
70
+ dataSource: 'static',
71
+ baseUrl: '',
72
+ headers: {},
73
+ description: `Invalid configuration - VITE_AUTH_MODE="${authModeRaw}"`,
74
+ suiteCRM: {
75
+ url: undefined,
76
+ proxyUrl: undefined,
77
+ appId: undefined,
78
+ workerSecret: undefined,
79
+ oauth2: {
80
+ clientId: undefined,
81
+ clientSecret: undefined,
82
+ tokenUrl: undefined,
83
+ username: undefined,
84
+ password: undefined,
85
+ },
86
+ }
87
+ };
88
+ }
89
+ // Cloudflare proxy mode (uses Cloudflare Pages Functions by default)
90
+ // Worker URL is optional - Pages Functions handle routing automatically
91
+ if (authMode === 'cloudflare_proxy') {
92
+ const workerUrl = getEnv('VITE_CLOUDFLARE_WORKER_URL');
93
+ // Cloudflare Pages Functions work without explicit worker URL
94
+ // The worker URL is only needed for separate Cloudflare Workers
95
+ // Pages Functions automatically handle /api/* routes
96
+ const baseUrl = workerUrl || '/api';
97
+ return {
98
+ mode: isLocal ? 'local' : 'remote',
99
+ authMode: 'cloudflare_proxy',
100
+ dataSource: 'static',
101
+ baseUrl,
102
+ headers: {
103
+ 'Content-Type': 'application/json'
104
+ },
105
+ description: workerUrl
106
+ ? (isLocal ? 'Local development with Cloudflare Worker proxy' : 'Remote development with Cloudflare Worker proxy')
107
+ : (isLocal ? 'Local development with Cloudflare Pages Functions' : 'Production with Cloudflare Pages Functions'),
108
+ mautic: {
109
+ proxyUrl: getEnv('VITE_MAUTIC_PROXY_URL')
110
+ },
111
+ suiteCRM: {
112
+ url: getEnv('VITE_SUITECRM_URL'),
113
+ proxyUrl: getEnv('VITE_SUITECRM_PROXY_URL'),
114
+ appId: undefined,
115
+ workerSecret: undefined,
116
+ oauth2: {
117
+ clientId: getEnv('VITE_SUITECRM_CLIENT_ID'),
118
+ clientSecret: getEnv('VITE_SUITECRM_CLIENT_SECRET'),
119
+ tokenUrl: getEnv('VITE_SUITECRM_TOKEN_URL'),
120
+ username: getEnv('VITE_SUITECRM_USERNAME'),
121
+ password: getEnv('VITE_SUITECRM_PASSWORD'),
122
+ },
123
+ }
124
+ };
125
+ }
126
+ // Direct WordPress mode (legacy - for local development only)
127
+ if (authMode === 'direct') {
128
+ const wpApiUrl = getEnv('VITE_WORDPRESS_API_URL');
129
+ if (!wpApiUrl) {
130
+ console.warn('⚠️ Direct mode requires: VITE_WORDPRESS_API_URL');
131
+ return {
132
+ mode: 'error',
133
+ authMode: 'error',
134
+ dataSource: 'static',
135
+ baseUrl: '',
136
+ headers: {},
137
+ description: 'Invalid configuration - missing WordPress API URL',
138
+ suiteCRM: {
139
+ url: undefined,
140
+ proxyUrl: undefined,
141
+ appId: undefined,
142
+ workerSecret: undefined,
143
+ oauth2: {
144
+ clientId: undefined,
145
+ clientSecret: undefined,
146
+ tokenUrl: undefined,
147
+ username: undefined,
148
+ password: undefined,
149
+ },
150
+ }
151
+ };
152
+ }
153
+ if (isDevEnvironment()) {
154
+ console.log('🔍 Using direct WordPress mode (legacy - for local development only)');
155
+ }
156
+ const localDev = getEnv('VITE_LOCAL_DEVELOPMENT') === 'true';
157
+ return {
158
+ mode: localDev ? 'local' : 'remote',
159
+ authMode: 'direct',
160
+ dataSource: 'hybrid',
161
+ baseUrl: wpApiUrl,
162
+ headers: { 'Content-Type': 'application/json' },
163
+ description: localDev ? 'Direct (local dev) without Access' : 'Direct mode',
164
+ mautic: { url: getEnv('VITE_MAUTIC_URL') },
165
+ suiteCRM: {
166
+ url: getEnv('VITE_SUITECRM_URL'),
167
+ proxyUrl: getEnv('VITE_SUITECRM_PROXY_URL'),
168
+ appId: undefined,
169
+ workerSecret: undefined,
170
+ oauth2: {
171
+ clientId: getEnv('VITE_SUITECRM_CLIENT_ID'),
172
+ clientSecret: getEnv('VITE_SUITECRM_CLIENT_SECRET'),
173
+ tokenUrl: getEnv('VITE_SUITECRM_TOKEN_URL'),
174
+ username: getEnv('VITE_SUITECRM_USERNAME'),
175
+ password: getEnv('VITE_SUITECRM_PASSWORD'),
176
+ },
177
+ }
178
+ };
179
+ }
180
+ // This should never be reached, but just in case
181
+ return {
182
+ mode: 'error',
183
+ authMode: 'error',
184
+ dataSource: 'static',
185
+ baseUrl: '',
186
+ headers: {},
187
+ description: 'Invalid configuration - unknown error',
188
+ suiteCRM: {
189
+ url: undefined,
190
+ proxyUrl: undefined,
191
+ appId: undefined,
192
+ workerSecret: undefined,
193
+ oauth2: {
194
+ clientId: undefined,
195
+ clientSecret: undefined,
196
+ tokenUrl: undefined,
197
+ username: undefined,
198
+ password: undefined,
199
+ },
200
+ }
201
+ };
202
+ };
203
+ // Get all possible configurations for development
204
+ const getDevelopmentConfigs = () => ({
205
+ local: {
206
+ mode: 'local',
207
+ authMode: 'cloudflare_proxy',
208
+ dataSource: 'static',
209
+ baseUrl: getEnv('VITE_CLOUDFLARE_WORKER_URL') || '',
210
+ headers: {
211
+ 'Content-Type': 'application/json'
212
+ },
213
+ description: 'Local development with Cloudflare Worker proxy (Secrets Store)',
214
+ suiteCRM: {
215
+ url: getEnv('VITE_SUITECRM_URL'),
216
+ proxyUrl: getEnv('VITE_SUITECRM_PROXY_URL'),
217
+ appId: undefined,
218
+ workerSecret: undefined,
219
+ oauth2: {
220
+ clientId: getEnv('VITE_SUITECRM_CLIENT_ID'),
221
+ clientSecret: getEnv('VITE_SUITECRM_CLIENT_SECRET'),
222
+ tokenUrl: undefined, // Will be built from base URL
223
+ username: getEnv('VITE_SUITECRM_USERNAME'),
224
+ password: getEnv('VITE_SUITECRM_PASSWORD'),
225
+ },
226
+ }
227
+ },
228
+ remote: {
229
+ mode: 'remote',
230
+ authMode: 'cloudflare_proxy',
231
+ dataSource: 'static',
232
+ baseUrl: getEnv('VITE_CLOUDFLARE_WORKER_URL') || '',
233
+ headers: {
234
+ 'Content-Type': 'application/json'
235
+ },
236
+ description: 'Remote development with Cloudflare Worker proxy (Secrets Store)',
237
+ suiteCRM: {
238
+ url: getEnv('VITE_SUITECRM_URL'),
239
+ proxyUrl: getEnv('VITE_SUITECRM_PROXY_URL'),
240
+ appId: undefined,
241
+ workerSecret: undefined,
242
+ oauth2: {
243
+ clientId: getEnv('VITE_SUITECRM_CLIENT_ID'),
244
+ clientSecret: getEnv('VITE_SUITECRM_CLIENT_SECRET'),
245
+ tokenUrl: undefined, // Will be built from base URL
246
+ username: getEnv('VITE_SUITECRM_USERNAME'),
247
+ password: getEnv('VITE_SUITECRM_PASSWORD'),
248
+ },
249
+ }
250
+ },
251
+ production: {
252
+ mode: 'production',
253
+ authMode: 'cloudflare_proxy',
254
+ dataSource: 'static',
255
+ baseUrl: getEnv('VITE_CLOUDFLARE_WORKER_URL') || '',
256
+ headers: {
257
+ 'Content-Type': 'application/json'
258
+ },
259
+ description: 'Production environment with Cloudflare Worker proxy (Secrets Store)',
260
+ suiteCRM: {
261
+ url: getEnv('VITE_SUITECRM_URL'),
262
+ proxyUrl: getEnv('VITE_SUITECRM_PROXY_URL'),
263
+ appId: undefined,
264
+ workerSecret: undefined,
265
+ oauth2: {
266
+ clientId: getEnv('VITE_SUITECRM_CLIENT_ID'),
267
+ clientSecret: getEnv('VITE_SUITECRM_CLIENT_SECRET'),
268
+ tokenUrl: undefined, // Will be built from base URL
269
+ username: getEnv('VITE_SUITECRM_USERNAME'),
270
+ password: getEnv('VITE_SUITECRM_PASSWORD'),
271
+ },
272
+ }
273
+ }
274
+ });
275
+ // Environment status and diagnostics
276
+ const getEnvironmentStatus = () => {
277
+ const config = getEnvironmentConfig();
278
+ const isLocal = isLocalDevelopment();
279
+ const authMode = getEnv('VITE_AUTH_MODE');
280
+ // Check if required credentials are available for each mode
281
+ const hasCloudflareCredentials = !!getEnv('VITE_CLOUDFLARE_WORKER_URL');
282
+ const hasWordPressApiUrl = !!getEnv('VITE_WORDPRESS_API_URL');
283
+ return {
284
+ currentConfig: config,
285
+ diagnostics: {
286
+ isLocalDevelopment: isLocal,
287
+ authMode: authMode,
288
+ hasCloudflareCredentials,
289
+ hasWordpressApiUrl: hasWordPressApiUrl,
290
+ cloudflareWorkerUrl: !!getEnv('VITE_CLOUDFLARE_WORKER_URL'),
291
+ cfAccessId: !!getEnv('VITE_CF_ACCESS_CLIENT_ID'),
292
+ cfAccessSecret: !!getEnv('VITE_CF_ACCESS_CLIENT_SECRET'),
293
+ mauticProxyUrl: !!getEnv('VITE_MAUTIC_PROXY_URL')
294
+ },
295
+ recommendations: {
296
+ // Only show recommendation if authMode is explicitly set to an invalid value
297
+ // Default is cloudflare_proxy, so no recommendation needed if not set
298
+ authMode: null, // Defaults to cloudflare_proxy, no warning needed
299
+ cloudflare: null // Pages Functions work without explicit worker URL
300
+ }
301
+ };
302
+ };
303
+ // Export current environment config as default
304
+ const currentEnv = getEnvironmentConfig();
305
+ const envStatus = getEnvironmentStatus();
306
+
307
+ /**
308
+ * Integration Configuration
309
+ * Centralized configuration for all third-party integrations
310
+ */
311
+ /**
312
+ * Get integration configuration with environment variable fallbacks
313
+ */
314
+ function getIntegrationConfig() {
315
+ isDevEnvironment();
316
+ return {
317
+ wordpress: {
318
+ enabled: true,
319
+ apiUrl: getEnv('VITE_WORDPRESS_API_URL') || '',
320
+ authMode: getEnv('VITE_AUTH_MODE') || 'direct',
321
+ },
322
+ supabase: {
323
+ enabled: getEnv('VITE_AUTH_MODE') === 'supabase_proxy',
324
+ url: getEnv('VITE_SUPABASE_URL') || '',
325
+ anonKey: getEnv('VITE_SUPABASE_ANON_KEY') || '',
326
+ serviceRoleKey: getEnv('VITE_SUPABASE_SERVICE_ROLE_KEY'),
327
+ },
328
+ gravityForms: {
329
+ enabled: !!(getEnv('VITE_CLOUDFLARE_WORKER_URL') || getEnv('VITE_WORDPRESS_API_URL')),
330
+ url: getEnv('VITE_WORDPRESS_API_URL'),
331
+ proxyUrl: getEnv('VITE_CLOUDFLARE_WORKER_URL'),
332
+ consumerKey: getEnv('VITE_GF_CONSUMER_KEY'),
333
+ consumerSecret: getEnv('VITE_GF_CONSUMER_SECRET'),
334
+ forms: {
335
+ 'contact': {
336
+ name: 'Contact Form',
337
+ type: 'contact',
338
+ successMessage: 'Thank you for your message. We\'ll get back to you soon!',
339
+ },
340
+ 'newsletter': {
341
+ name: 'Newsletter Signup',
342
+ type: 'newsletter',
343
+ successMessage: 'Thank you for subscribing to our newsletter!',
344
+ },
345
+ 'support': {
346
+ name: 'Support Request',
347
+ type: 'support',
348
+ successMessage: 'Your support request has been submitted successfully.',
349
+ },
350
+ },
351
+ },
352
+ mautic: {
353
+ enabled: !!(getEnv('VITE_MAUTIC_PROXY_URL') || getEnv('VITE_MAUTIC_URL')),
354
+ url: getEnv('VITE_MAUTIC_URL') || '',
355
+ proxyUrl: getEnv('VITE_MAUTIC_PROXY_URL'),
356
+ forms: {
357
+ '1': {
358
+ name: 'Newsletter Signup',
359
+ type: 'newsletter',
360
+ successMessage: 'Thank you for subscribing to our newsletter!',
361
+ postAction: 'message',
362
+ postActionProperty: 'Thank you for your submission!'
363
+ },
364
+ '2': {
365
+ name: 'Contact Form',
366
+ type: 'contact',
367
+ successMessage: 'Thank you for contacting us! We\'ll get back to you soon.',
368
+ postAction: 'message',
369
+ postActionProperty: 'Thank you for your message!'
370
+ },
371
+ '3': {
372
+ name: 'Lead Capture',
373
+ type: 'lead',
374
+ successMessage: 'Thank you for your interest! We\'ll be in touch.',
375
+ postAction: 'message',
376
+ postActionProperty: 'Thank you for your submission!'
377
+ }
378
+ }
379
+ },
380
+ suiteCRM: {
381
+ enabled: !!(getEnv('VITE_SUITECRM_URL') && getEnv('VITE_SUITECRM_CLIENT_ID') && getEnv('VITE_SUITECRM_CLIENT_SECRET')),
382
+ url: getEnv('VITE_SUITECRM_URL'),
383
+ proxyUrl: getEnv('VITE_SUITECRM_PROXY_URL'),
384
+ appId: undefined,
385
+ workerSecret: undefined,
386
+ oauth2: {
387
+ clientId: getEnv('VITE_SUITECRM_CLIENT_ID'),
388
+ clientSecret: getEnv('VITE_SUITECRM_CLIENT_SECRET'),
389
+ username: getEnv('VITE_SUITECRM_USERNAME'),
390
+ password: getEnv('VITE_SUITECRM_PASSWORD'),
391
+ },
392
+ },
393
+ chatwoot: {
394
+ enabled: !!(getEnv('VITE_CHATWOOT_WEBSITE_TOKEN') && getEnv('VITE_CHATWOOT_BASE_URL')),
395
+ websiteToken: getEnv('VITE_CHATWOOT_WEBSITE_TOKEN') || '',
396
+ baseUrl: getEnv('VITE_CHATWOOT_BASE_URL') || '',
397
+ locale: 'en',
398
+ type: 'standard',
399
+ launcherTitle: 'Chat',
400
+ hideMessageBubble: false,
401
+ position: 'right',
402
+ showPopoutButton: false,
403
+ },
404
+ analytics: {
405
+ googleAnalytics: { enabled: false },
406
+ googleTagManager: { enabled: false },
407
+ facebookPixel: { enabled: false },
408
+ linkedinInsight: { enabled: false },
409
+ },
410
+ seo: {
411
+ defaultTitle: '',
412
+ defaultDescription: '',
413
+ defaultImage: '',
414
+ siteName: '',
415
+ siteUrl: '',
416
+ },
417
+ performance: {
418
+ enableLazyLoading: true,
419
+ enableImageOptimization: true,
420
+ enableCodeSplitting: true,
421
+ enableServiceWorker: false,
422
+ enableCaching: true,
423
+ }
424
+ };
425
+ }
426
+ /**
427
+ * Validate integration configuration
428
+ * Only validates integrations that are actually enabled
429
+ */
430
+ function validateIntegrationConfig() {
431
+ const config = getIntegrationConfig();
432
+ const errors = [];
433
+ // WordPress validation - only if enabled
434
+ if (config.wordpress.enabled && !config.wordpress.apiUrl && !config.gravityForms.proxyUrl) {
435
+ errors.push('WordPress API URL is required when WordPress is enabled (unless using Gravity Forms proxy)');
436
+ }
437
+ // Supabase validation - only if enabled
438
+ if (config.supabase.enabled && (!config.supabase.url || !config.supabase.anonKey)) {
439
+ errors.push('Supabase URL and anonymous key are required when Supabase is enabled');
440
+ }
441
+ // Gravity Forms validation - only if enabled
442
+ // Note: Cloudflare Pages Functions handle routing, so proxyUrl is optional
443
+ // Only validate if explicitly trying to use a separate worker
444
+ if (config.gravityForms.enabled) {
445
+ // Gravity Forms can work via Pages Functions (/api/gravity-forms-submit)
446
+ // Only require proxy URL if using a separate worker
447
+ const hasWorkerUrl = !!getEnv('VITE_CLOUDFLARE_WORKER_URL');
448
+ if (!hasWorkerUrl && isDevEnvironment()) {
449
+ // Using Pages Functions - this is fine, just log info
450
+ console.log('ℹ️ Gravity Forms will use Cloudflare Pages Functions (/api/gravity-forms-submit)');
451
+ }
452
+ }
453
+ // Mautic validation - only if enabled
454
+ // Mautic can work via Pages Functions, so proxy URL is optional
455
+ if (config.mautic.enabled) {
456
+ const hasProxyUrl = !!config.mautic.proxyUrl;
457
+ const hasWorkerUrl = !!getEnv('VITE_CLOUDFLARE_WORKER_URL');
458
+ if (!hasProxyUrl && !hasWorkerUrl && isDevEnvironment()) {
459
+ // Using Pages Functions - this is fine
460
+ console.log('ℹ️ Mautic will use Cloudflare Pages Functions (/api/mautic-submit)');
461
+ }
462
+ }
463
+ // SuiteCRM validation - only if enabled
464
+ if (config.suiteCRM.enabled && (!config.suiteCRM.url || !config.suiteCRM.oauth2?.clientId || !config.suiteCRM.oauth2?.clientSecret)) {
465
+ errors.push('SuiteCRM URL, client ID, and client secret are required when SuiteCRM is enabled');
466
+ }
467
+ // Chatwoot validation - only if enabled
468
+ if (config.chatwoot.enabled && !config.chatwoot.websiteToken) {
469
+ errors.push('Chatwoot website token is required when Chatwoot is enabled');
470
+ }
471
+ return errors;
472
+ }
473
+ /**
474
+ * Get specific integration configuration
475
+ */
476
+ function getWordPressConfig() {
477
+ return getIntegrationConfig().wordpress;
478
+ }
479
+ function getSupabaseConfig() {
480
+ return getIntegrationConfig().supabase;
481
+ }
482
+ function getGravityFormsConfig() {
483
+ return getIntegrationConfig().gravityForms;
484
+ }
485
+ function getMauticConfig() {
486
+ return getIntegrationConfig().mautic;
487
+ }
488
+ function getSuiteCRMConfig() {
489
+ return getIntegrationConfig().suiteCRM;
490
+ }
491
+ function getChatwootConfig() {
492
+ return getIntegrationConfig().chatwoot;
493
+ }
494
+ function getAnalyticsConfig() {
495
+ return getIntegrationConfig().analytics;
496
+ }
497
+ function getSEOConfig() {
498
+ return getIntegrationConfig().seo;
499
+ }
500
+ function getPerformanceConfig() {
501
+ return getIntegrationConfig().performance;
502
+ }
503
+
504
+ exports.currentEnv = currentEnv;
505
+ exports.envStatus = envStatus;
506
+ exports.getAnalyticsConfig = getAnalyticsConfig;
507
+ exports.getChatwootConfig = getChatwootConfig;
508
+ exports.getDevelopmentConfigs = getDevelopmentConfigs;
509
+ exports.getEnvironmentConfig = getEnvironmentConfig;
510
+ exports.getEnvironmentStatus = getEnvironmentStatus;
511
+ exports.getGravityFormsConfig = getGravityFormsConfig;
512
+ exports.getIntegrationConfig = getIntegrationConfig;
513
+ exports.getMauticConfig = getMauticConfig;
514
+ exports.getPerformanceConfig = getPerformanceConfig;
515
+ exports.getSEOConfig = getSEOConfig;
516
+ exports.getSuiteCRMConfig = getSuiteCRMConfig;
517
+ exports.getSupabaseConfig = getSupabaseConfig;
518
+ exports.getWordPressConfig = getWordPressConfig;
519
+ exports.validateIntegrationConfig = validateIntegrationConfig;
520
+ //# sourceMappingURL=config.cjs.map