@pixelated-tech/components 3.13.16 → 3.14.1
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/dist/components/admin/site-health/google.api.integration.js +5 -4
- package/dist/components/admin/site-health/site-health-cloudwatch.integration.js +3 -2
- package/dist/components/admin/site-health/site-health-dependency-vulnerabilities.js +1 -3
- package/dist/components/config/crypto.js +17 -1
- package/dist/components/general/404.js +1 -1
- package/dist/components/general/cache-manager.js +19 -2
- package/dist/components/general/callout.js +1 -1
- package/dist/components/general/carousel.drag.js +21 -24
- package/dist/components/general/carousel.js +3 -3
- package/dist/components/general/countup.js +1 -1
- package/dist/components/general/intersection-observer.js +4 -0
- package/dist/components/general/metadata.functions.js +2 -2
- package/dist/components/general/proxy-handler.js +2 -2
- package/dist/components/general/semantic.js +3 -6
- package/dist/components/general/sitemap.js +2 -1
- package/dist/components/general/smartimage.js +2 -4
- package/dist/components/general/styleguide.js +1 -1
- package/dist/components/general/tiles.js +2 -2
- package/dist/components/general/timeline.js +1 -1
- package/dist/components/general/utilities.js +68 -0
- package/dist/components/integrations/contentful.delivery.js +16 -16
- package/dist/components/integrations/contentful.items.components.js +2 -11
- package/dist/components/integrations/flickr.js +7 -4
- package/dist/components/integrations/google.reviews.components.js +3 -0
- package/dist/components/integrations/googleplaces.js +144 -0
- package/dist/components/integrations/socialcard.js +5 -2
- package/dist/components/integrations/wordpress.components.js +2 -1
- package/dist/components/shoppingcart/ebay.components.js +5 -5
- package/dist/components/shoppingcart/ebay.functions.js +5 -3
- package/dist/components/shoppingcart/paypal.js +1 -1
- package/dist/components/shoppingcart/shipping.to.json +3 -4
- package/dist/components/shoppingcart/shoppingcart.components.js +7 -5
- package/dist/components/shoppingcart/shoppingcart.css +1 -1
- package/dist/components/shoppingcart/shoppingcart.functions.js +5 -14
- package/dist/components/sitebuilder/config/ConfigEngine.js +2 -2
- package/dist/components/sitebuilder/config/google-fonts.js +3 -3
- package/dist/components/sitebuilder/form/formcomponents.js +151 -0
- package/dist/components/sitebuilder/form/formutils.js +3 -0
- package/dist/components/sitebuilder/page/lib/pageStorageContentful.js +2 -2
- package/dist/config/pixelated.config.json.enc +1 -1
- package/dist/data/form.json +18 -0
- package/dist/index.adminserver.js +1 -3
- package/dist/index.js +1 -1
- package/dist/index.server.js +1 -0
- package/dist/scripts/create-pixelated-app.js +187 -79
- package/dist/scripts/create-pixelated-app.json +56 -1
- package/dist/scripts/pixelated-eslint-plugin.js +142 -0
- package/dist/scripts/release.sh +14 -1
- package/dist/scripts/update.sh +2 -0
- package/dist/types/components/admin/deploy/deployment.integration.d.ts +1 -0
- package/dist/types/components/admin/deploy/deployment.integration.d.ts.map +1 -1
- package/dist/types/components/admin/site-health/google.api.integration.d.ts.map +1 -1
- package/dist/types/components/admin/site-health/site-health-cloudwatch.integration.d.ts.map +1 -1
- package/dist/types/components/config/config.types.d.ts +24 -0
- package/dist/types/components/config/config.types.d.ts.map +1 -1
- package/dist/types/components/config/crypto.d.ts +1 -0
- package/dist/types/components/config/crypto.d.ts.map +1 -1
- package/dist/types/components/general/404.d.ts.map +1 -1
- package/dist/types/components/general/cache-manager.d.ts +16 -2
- package/dist/types/components/general/cache-manager.d.ts.map +1 -1
- package/dist/types/components/general/callout.d.ts.map +1 -1
- package/dist/types/components/general/carousel.drag.d.ts.map +1 -1
- package/dist/types/components/general/intersection-observer.d.ts.map +1 -1
- package/dist/types/components/general/sitemap.d.ts.map +1 -1
- package/dist/types/components/general/smartimage.d.ts.map +1 -1
- package/dist/types/components/general/utilities.d.ts +37 -0
- package/dist/types/components/general/utilities.d.ts.map +1 -1
- package/dist/types/components/integrations/contentful.delivery.d.ts +16 -16
- package/dist/types/components/integrations/contentful.items.components.d.ts.map +1 -1
- package/dist/types/components/integrations/flickr.d.ts.map +1 -1
- package/dist/types/components/integrations/google.reviews.components.d.ts.map +1 -1
- package/dist/types/components/integrations/googleplaces.d.ts +61 -0
- package/dist/types/components/integrations/googleplaces.d.ts.map +1 -0
- package/dist/types/components/integrations/socialcard.d.ts.map +1 -1
- package/dist/types/components/integrations/wordpress.components.d.ts.map +1 -1
- package/dist/types/components/shoppingcart/ebay.functions.d.ts.map +1 -1
- package/dist/types/components/shoppingcart/shoppingcart.components.d.ts.map +1 -1
- package/dist/types/components/shoppingcart/shoppingcart.functions.d.ts +2 -2
- package/dist/types/components/shoppingcart/shoppingcart.functions.d.ts.map +1 -1
- package/dist/types/components/sitebuilder/form/formcomponents.d.ts +22 -0
- package/dist/types/components/sitebuilder/form/formcomponents.d.ts.map +1 -1
- package/dist/types/components/sitebuilder/form/formutils.d.ts.map +1 -1
- package/dist/types/index.adminserver.d.ts +1 -3
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.server.d.ts +1 -0
- package/dist/types/scripts/create-pixelated-app.d.ts +3 -0
- package/dist/types/scripts/create-pixelated-app.d.ts.map +1 -1
- package/dist/types/scripts/pixelated-eslint-plugin.d.ts +20 -0
- package/dist/types/stories/integrations/contentful.items.stories.d.ts.map +1 -0
- package/dist/types/stories/integrations/contentful.stories.d.ts.map +1 -0
- package/dist/types/stories/integrations/google.reviews.stories.d.ts.map +1 -0
- package/dist/types/stories/integrations/googlesearch.stories.d.ts.map +1 -0
- package/dist/types/stories/integrations/gravatar.stories.d.ts.map +1 -0
- package/dist/types/stories/integrations/instagram.stories.d.ts.map +1 -0
- package/dist/types/stories/integrations/wordpress.stories.d.ts.map +1 -0
- package/dist/types/test/test-utils.d.ts +2 -0
- package/dist/types/test/test-utils.d.ts.map +1 -1
- package/dist/types/tests/404.test.d.ts +2 -0
- package/dist/types/tests/404.test.d.ts.map +1 -0
- package/dist/types/tests/carousel.drag.test.d.ts +2 -0
- package/dist/types/tests/carousel.drag.test.d.ts.map +1 -0
- package/dist/types/tests/carouselDrag.test.d.ts +2 -0
- package/dist/types/tests/carouselDrag.test.d.ts.map +1 -0
- package/dist/types/tests/componentAnalysis.test.d.ts +2 -0
- package/dist/types/tests/componentAnalysis.test.d.ts.map +1 -0
- package/dist/types/tests/componentDiscovery.test.d.ts +2 -0
- package/dist/types/tests/componentDiscovery.test.d.ts.map +1 -0
- package/dist/types/tests/componentMap.test.d.ts +2 -0
- package/dist/types/tests/componentMap.test.d.ts.map +1 -0
- package/dist/types/tests/contentful.items.components.test.d.ts +2 -0
- package/dist/types/tests/contentful.items.components.test.d.ts.map +1 -0
- package/dist/types/tests/contentful.management.test.d.ts +2 -0
- package/dist/types/tests/contentful.management.test.d.ts.map +1 -0
- package/dist/types/tests/contentfulManagement.test.d.ts +2 -0
- package/dist/types/tests/contentfulManagement.test.d.ts.map +1 -0
- package/dist/types/tests/countup.test.d.ts +2 -0
- package/dist/types/tests/countup.test.d.ts.map +1 -0
- package/dist/types/tests/crypto.test.d.ts +2 -0
- package/dist/types/tests/crypto.test.d.ts.map +1 -0
- package/dist/types/tests/deployment.integration.test.d.ts +2 -0
- package/dist/types/tests/deployment.integration.test.d.ts.map +1 -0
- package/dist/types/tests/ebay.components.test.d.ts +2 -0
- package/dist/types/tests/ebay.components.test.d.ts.map +1 -0
- package/dist/types/tests/ebayComponents.test.d.ts +2 -0
- package/dist/types/tests/ebayComponents.test.d.ts.map +1 -0
- package/dist/types/tests/flickr.test.d.ts +2 -0
- package/dist/types/tests/flickr.test.d.ts.map +1 -0
- package/dist/types/tests/formgoogleplacesinput.test.d.ts +2 -0
- package/dist/types/tests/formgoogleplacesinput.test.d.ts.map +1 -0
- package/dist/types/tests/formutils.test.d.ts +2 -0
- package/dist/types/tests/formutils.test.d.ts.map +1 -0
- package/dist/types/tests/formvalidator.test.d.ts +2 -0
- package/dist/types/tests/formvalidator.test.d.ts.map +1 -0
- package/dist/types/tests/gemini-api.client.test.d.ts +2 -0
- package/dist/types/tests/gemini-api.client.test.d.ts.map +1 -0
- package/dist/types/tests/gemini-api.server.test.d.ts +2 -0
- package/dist/types/tests/gemini-api.server.test.d.ts.map +1 -0
- package/dist/types/tests/geminiApi.test.d.ts +2 -0
- package/dist/types/tests/geminiApi.test.d.ts.map +1 -0
- package/dist/types/tests/google.reviews.components.test.d.ts +2 -0
- package/dist/types/tests/google.reviews.components.test.d.ts.map +1 -0
- package/dist/types/tests/googleanalytics.test.d.ts +2 -0
- package/dist/types/tests/googleanalytics.test.d.ts.map +1 -0
- package/dist/types/tests/googlemap.test.d.ts +2 -0
- package/dist/types/tests/googlemap.test.d.ts.map +1 -0
- package/dist/types/tests/gravatar.functions.test.d.ts +2 -0
- package/dist/types/tests/gravatar.functions.test.d.ts.map +1 -0
- package/dist/types/tests/hubspot.components.test.d.ts +2 -0
- package/dist/types/tests/hubspot.components.test.d.ts.map +1 -0
- package/dist/types/tests/image-utils.test.d.ts +2 -0
- package/dist/types/tests/image-utils.test.d.ts.map +1 -0
- package/dist/types/tests/instagram.components.test.d.ts +2 -0
- package/dist/types/tests/instagram.components.test.d.ts.map +1 -0
- package/dist/types/tests/instagram.functions.test.d.ts +2 -0
- package/dist/types/tests/instagram.functions.test.d.ts.map +1 -0
- package/dist/types/tests/intersection-observer.test.d.ts +2 -0
- package/dist/types/tests/intersection-observer.test.d.ts.map +1 -0
- package/dist/types/tests/metadata.functions.test.d.ts +2 -0
- package/dist/types/tests/metadata.functions.test.d.ts.map +1 -0
- package/dist/types/tests/metadataComponents.test.d.ts +2 -0
- package/dist/types/tests/metadataComponents.test.d.ts.map +1 -0
- package/dist/types/tests/page-storage.test.d.ts +2 -0
- package/dist/types/tests/page-storage.test.d.ts.map +1 -0
- package/dist/types/tests/pageStorageContentful.test.d.ts +2 -0
- package/dist/types/tests/pageStorageContentful.test.d.ts.map +1 -0
- package/dist/types/tests/pageStorageLocal.test.d.ts +2 -0
- package/dist/types/tests/pageStorageLocal.test.d.ts.map +1 -0
- package/dist/types/tests/pixelated.test.d.ts +2 -0
- package/dist/types/tests/pixelated.test.d.ts.map +1 -0
- package/dist/types/tests/propTypeIntrospection.test.d.ts +2 -0
- package/dist/types/tests/propTypeIntrospection.test.d.ts.map +1 -0
- package/dist/types/tests/save-route-example.test.d.ts +2 -0
- package/dist/types/tests/save-route-example.test.d.ts.map +1 -0
- package/dist/types/tests/saveRouteExample.test.d.ts +2 -0
- package/dist/types/tests/saveRouteExample.test.d.ts.map +1 -0
- package/dist/types/tests/seoConstants.test.d.ts +2 -0
- package/dist/types/tests/seoConstants.test.d.ts.map +1 -0
- package/dist/types/tests/site-health-accessibility.test.d.ts +2 -0
- package/dist/types/tests/site-health-accessibility.test.d.ts.map +1 -0
- package/dist/types/tests/site-health-cloudwatch.integration.test.d.ts +2 -0
- package/dist/types/tests/site-health-cloudwatch.integration.test.d.ts.map +1 -0
- package/dist/types/tests/site-health-dependency-vulnerabilities.test.d.ts +2 -0
- package/dist/types/tests/site-health-dependency-vulnerabilities.test.d.ts.map +1 -0
- package/dist/types/tests/site-health-github.test.d.ts +2 -0
- package/dist/types/tests/site-health-github.test.d.ts.map +1 -0
- package/dist/types/tests/site-health-google-analytics.integration.test.d.ts +2 -0
- package/dist/types/tests/site-health-google-analytics.integration.test.d.ts.map +1 -0
- package/dist/types/tests/site-health-google-analytics.test.d.ts +2 -0
- package/dist/types/tests/site-health-google-analytics.test.d.ts.map +1 -0
- package/dist/types/tests/site-health-google-search-console.integration.test.d.ts +2 -0
- package/dist/types/tests/site-health-google-search-console.integration.test.d.ts.map +1 -0
- package/dist/types/tests/site-health-google-search-console.test.d.ts +2 -0
- package/dist/types/tests/site-health-google-search-console.test.d.ts.map +1 -0
- package/dist/types/tests/site-health-mock-context.test.d.ts +2 -0
- package/dist/types/tests/site-health-mock-context.test.d.ts.map +1 -0
- package/dist/types/tests/site-health-on-site-seo.test.d.ts +2 -0
- package/dist/types/tests/site-health-on-site-seo.test.d.ts.map +1 -0
- package/dist/types/tests/site-health-performance.test.d.ts +2 -0
- package/dist/types/tests/site-health-performance.test.d.ts.map +1 -0
- package/dist/types/tests/site-health-security.integration.test.d.ts +2 -0
- package/dist/types/tests/site-health-security.integration.test.d.ts.map +1 -0
- package/dist/types/tests/site-health-security.test.d.ts +2 -0
- package/dist/types/tests/site-health-security.test.d.ts.map +1 -0
- package/dist/types/tests/site-health-seo.test.d.ts +2 -0
- package/dist/types/tests/site-health-seo.test.d.ts.map +1 -0
- package/dist/types/tests/site-health-uptime.integration.test.d.ts +2 -0
- package/dist/types/tests/site-health-uptime.integration.test.d.ts.map +1 -0
- package/dist/types/tests/site-health-uptime.test.d.ts +2 -0
- package/dist/types/tests/site-health-uptime.test.d.ts.map +1 -0
- package/dist/types/tests/siteHealthGaIntegration.test.d.ts +2 -0
- package/dist/types/tests/siteHealthGaIntegration.test.d.ts.map +1 -0
- package/dist/types/tests/siteHealthGscIntegration.test.d.ts +2 -0
- package/dist/types/tests/siteHealthGscIntegration.test.d.ts.map +1 -0
- package/dist/types/tests/spotify.components.test.d.ts +2 -0
- package/dist/types/tests/spotify.components.test.d.ts.map +1 -0
- package/dist/types/tests/spotify.functions.test.d.ts +2 -0
- package/dist/types/tests/spotify.functions.test.d.ts.map +1 -0
- package/dist/types/tests/test-utils.d.ts +7 -0
- package/dist/types/tests/test-utils.d.ts.map +1 -0
- package/dist/types/tests/usePageBuilder.test.d.ts +2 -0
- package/dist/types/tests/usePageBuilder.test.d.ts.map +1 -0
- package/package.json +34 -30
- package/dist/components/admin/site-health/site-health-google-analytics.integration.js +0 -6
- package/dist/components/admin/site-health/site-health-google-search-console.integration.js +0 -6
- package/dist/components/general/proxy-csp-listener.js +0 -20
- package/dist/scripts/create-pixelated-app-template-mapper.js +0 -80
- package/dist/types/components/admin/site-health/site-health-google-analytics.integration.d.ts +0 -6
- package/dist/types/components/admin/site-health/site-health-google-analytics.integration.d.ts.map +0 -1
- package/dist/types/components/admin/site-health/site-health-google-search-console.integration.d.ts +0 -6
- package/dist/types/components/admin/site-health/site-health-google-search-console.integration.d.ts.map +0 -1
- package/dist/types/components/general/proxy-csp-listener.d.ts +0 -15
- package/dist/types/components/general/proxy-csp-listener.d.ts.map +0 -1
- package/dist/types/scripts/create-pixelated-app-template-mapper.d.ts +0 -5
- package/dist/types/scripts/create-pixelated-app-template-mapper.d.ts.map +0 -1
- package/dist/types/stories/general/callout.many.stories.d.ts +0 -7
- package/dist/types/stories/general/callout.many.stories.d.ts.map +0 -1
- package/dist/types/stories/general/contentful.item.stories.d.ts +0 -12
- package/dist/types/stories/general/contentful.item.stories.d.ts.map +0 -1
- package/dist/types/stories/general/contentful.items.stories.d.ts.map +0 -1
- package/dist/types/stories/general/contentful.stories.d.ts.map +0 -1
- package/dist/types/stories/general/global-error.stories.d.ts +0 -26
- package/dist/types/stories/general/global-error.stories.d.ts.map +0 -1
- package/dist/types/stories/general/google.reviews.stories.d.ts.map +0 -1
- package/dist/types/stories/general/googleanalytics.stories.d.ts +0 -14
- package/dist/types/stories/general/googleanalytics.stories.d.ts.map +0 -1
- package/dist/types/stories/general/googlesearch.stories.d.ts.map +0 -1
- package/dist/types/stories/general/gravatar.stories.d.ts.map +0 -1
- package/dist/types/stories/general/instagram.stories.d.ts.map +0 -1
- package/dist/types/stories/general/loading.stories.d.ts +0 -11
- package/dist/types/stories/general/loading.stories.d.ts.map +0 -1
- package/dist/types/stories/general/metadata.stories.d.ts +0 -25
- package/dist/types/stories/general/metadata.stories.d.ts.map +0 -1
- package/dist/types/stories/general/schema.stories.d.ts +0 -62
- package/dist/types/stories/general/schema.stories.d.ts.map +0 -1
- package/dist/types/stories/general/sitemap.stories.d.ts +0 -8
- package/dist/types/stories/general/sitemap.stories.d.ts.map +0 -1
- package/dist/types/stories/general/wordpress.stories.d.ts.map +0 -1
- package/dist/types/stories/integrations/schema-podcast.stories.d.ts +0 -45
- package/dist/types/stories/integrations/schema-podcast.stories.d.ts.map +0 -1
- /package/dist/types/stories/{general → integrations}/contentful.items.stories.d.ts +0 -0
- /package/dist/types/stories/{general → integrations}/contentful.stories.d.ts +0 -0
- /package/dist/types/stories/{general → integrations}/google.reviews.stories.d.ts +0 -0
- /package/dist/types/stories/{general → integrations}/googlesearch.stories.d.ts +0 -0
- /package/dist/types/stories/{general → integrations}/gravatar.stories.d.ts +0 -0
- /package/dist/types/stories/{general → integrations}/instagram.stories.d.ts +0 -0
- /package/dist/types/stories/{general → integrations}/wordpress.stories.d.ts +0 -0
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
"use server";
|
|
7
7
|
import { google } from 'googleapis';
|
|
8
8
|
import { CacheManager } from '../../general/cache-manager';
|
|
9
|
+
import { getDomain } from '../../general/utilities';
|
|
9
10
|
import { calculateDateRanges, formatChartDate, getCachedData, setCachedData } from './google.api.utils';
|
|
10
11
|
// Migration-time debug flag (owner requested): verbose cache traces during migration
|
|
11
12
|
const debug = false; // keep as literal during migration for traceability
|
|
@@ -72,8 +73,8 @@ export async function createSearchConsoleClient(config) {
|
|
|
72
73
|
auth: result.auth
|
|
73
74
|
};
|
|
74
75
|
}
|
|
75
|
-
// Cache for analytics data (1 hour)
|
|
76
|
-
const analyticsCache = new CacheManager({
|
|
76
|
+
// Cache for analytics data (1 hour) — isolated per domain
|
|
77
|
+
const analyticsCache = new CacheManager({ domain: getDomain(), namespace: 'analytics', ttl: 60 * 60 * 1000 });
|
|
77
78
|
/**
|
|
78
79
|
* Get Google Analytics data for a site with current/previous period comparison
|
|
79
80
|
*/
|
|
@@ -168,8 +169,8 @@ export async function getGoogleAnalyticsData(config, siteName, startDate, endDat
|
|
|
168
169
|
};
|
|
169
170
|
}
|
|
170
171
|
}
|
|
171
|
-
// Cache for search console data (1 hour)
|
|
172
|
-
const searchConsoleCache = new CacheManager({
|
|
172
|
+
// Cache for search console data (1 hour) — isolated per domain
|
|
173
|
+
const searchConsoleCache = new CacheManager({ domain: getDomain(), namespace: 'searchconsole', ttl: 60 * 60 * 1000 });
|
|
173
174
|
/**
|
|
174
175
|
* Get Google Search Console data for a site with current/previous period comparison
|
|
175
176
|
*/
|
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
"use server";
|
|
6
6
|
import { CloudWatchClient, GetMetricDataCommand } from '@aws-sdk/client-cloudwatch';
|
|
7
7
|
import { CacheManager } from '../../general/cache-manager';
|
|
8
|
+
import { getDomain } from '../../general/utilities';
|
|
8
9
|
import { getFullPixelatedConfig } from '../../config/config';
|
|
9
10
|
const debug = false; // migration-time verbose logging
|
|
10
|
-
// Cache for health check data (15 minutes)
|
|
11
|
-
const healthCheckCache = new CacheManager({
|
|
11
|
+
// Cache for health check data (15 minutes) — isolated per domain
|
|
12
|
+
const healthCheckCache = new CacheManager({ domain: getDomain(), namespace: 'cloudwatch', ttl: 15 * 60 * 1000 });
|
|
12
13
|
/**
|
|
13
14
|
* Get health check data for a site using CloudWatch metrics
|
|
14
15
|
*/
|
|
@@ -37,8 +37,6 @@ export function SiteHealthDependencyVulnerabilities({ siteName }) {
|
|
|
37
37
|
data.status === 'Moderate Risk' ? '#f59e0b' :
|
|
38
38
|
data.status === 'High Risk' ? '#ef4444' :
|
|
39
39
|
data.status === 'Critical' ? '#ef4444' : '#6b7280'
|
|
40
|
-
} }) })] }) }), _jsxs("div", { className: "health-audit-item", children: [_jsx("span", { className: "health-audit-icon", style: { color: '#10b981' }, children: "\u2713" }), _jsx("div", { className: "health-audit-content", children: _jsxs("span", { className: "health-audit-title", children: ["Dependencies: ", data.totalDependencies || data.dependencies || 0] }) })] }), data.vulnerabilities && data.vulnerabilities.length > 0 && (_jsxs("div", { children: [_jsxs("h5", { style: { fontSize: '1rem', fontWeight: '600', marginBottom: '1rem' }, children: ["Vulnerabilities (", data.summary.total, ")"] }), _jsx("div", { className: "health-audit-list", children: data.vulnerabilities.map((vuln, index) => (
|
|
41
|
-
// eslint-disable-next-line pixelated/class-name-kebab-case
|
|
42
|
-
_jsx("div", { className: `health-vulnerability-item health-vulnerability-${vuln.severity}`, children: _jsxs("div", { className: "health-vulnerability-header", children: [_jsx("span", { className: "health-vulnerability-severity", children: vuln.severity }), _jsxs("div", { children: [_jsx("span", { className: "health-vulnerability-name", children: vuln.name }), vuln.title && (_jsx("p", { className: "health-vulnerability-details", children: vuln.title })), _jsxs("div", { className: "health-vulnerability-meta", children: [_jsxs("span", { className: "health-vulnerability-range", children: ["Range: ", vuln.range] }), vuln.fixAvailable && (_jsx("span", { className: "health-vulnerability-fix", children: "\u2713 Fix available" }))] }), vuln.url && (_jsx("a", { href: vuln.url, target: "_blank", rel: "noopener noreferrer", className: "health-vulnerability-link", children: "View details \u2192" }))] })] }) }, index))) })] })), (!data.vulnerabilities || data.vulnerabilities.length === 0) && data.status === 'Secure' && (_jsxs("div", { className: "health-audit-item", children: [_jsx("span", { className: "health-audit-icon", style: { color: '#10b981' }, children: "\u2713" }), _jsx("div", { className: "health-audit-content", children: _jsx("span", { className: "health-audit-title", children: "No vulnerabilities found" }) })] })), _jsxs("p", { className: "health-timestamp", children: ["Last checked: ", new Date(data.timestamp).toLocaleString()] })] }));
|
|
40
|
+
} }) })] }) }), _jsxs("div", { className: "health-audit-item", children: [_jsx("span", { className: "health-audit-icon", style: { color: '#10b981' }, children: "\u2713" }), _jsx("div", { className: "health-audit-content", children: _jsxs("span", { className: "health-audit-title", children: ["Dependencies: ", data.totalDependencies || data.dependencies || 0] }) })] }), data.vulnerabilities && data.vulnerabilities.length > 0 && (_jsxs("div", { children: [_jsxs("h5", { style: { fontSize: '1rem', fontWeight: '600', marginBottom: '1rem' }, children: ["Vulnerabilities (", data.summary.total, ")"] }), _jsx("div", { className: "health-audit-list", children: data.vulnerabilities.map((vuln, index) => (_jsx("div", { className: `health-vulnerability-item health-vulnerability-${vuln.severity}`, children: _jsxs("div", { className: "health-vulnerability-header", children: [_jsx("span", { className: "health-vulnerability-severity", children: vuln.severity }), _jsxs("div", { children: [_jsx("span", { className: "health-vulnerability-name", children: vuln.name }), vuln.title && (_jsx("p", { className: "health-vulnerability-details", children: vuln.title })), _jsxs("div", { className: "health-vulnerability-meta", children: [_jsxs("span", { className: "health-vulnerability-range", children: ["Range: ", vuln.range] }), vuln.fixAvailable && (_jsx("span", { className: "health-vulnerability-fix", children: "\u2713 Fix available" }))] }), vuln.url && (_jsx("a", { href: vuln.url, target: "_blank", rel: "noopener noreferrer", className: "health-vulnerability-link", children: "View details \u2192" }))] })] }) }, index))) })] })), (!data.vulnerabilities || data.vulnerabilities.length === 0) && data.status === 'Secure' && (_jsxs("div", { className: "health-audit-item", children: [_jsx("span", { className: "health-audit-icon", style: { color: '#10b981' }, children: "\u2713" }), _jsx("div", { className: "health-audit-content", children: _jsx("span", { className: "health-audit-title", children: "No vulnerabilities found" }) })] })), _jsxs("p", { className: "health-timestamp", children: ["Last checked: ", new Date(data.timestamp).toLocaleString()] })] }));
|
|
43
41
|
} }));
|
|
44
42
|
}
|
|
@@ -56,7 +56,23 @@ export function decrypt(payload, keyHex) {
|
|
|
56
56
|
}
|
|
57
57
|
/**
|
|
58
58
|
* Checks if a string is encrypted using our format.
|
|
59
|
+
* Validates that the string has the proper structure: pxl:v1:iv:authTag:encryptedContent
|
|
59
60
|
*/
|
|
60
61
|
export function isEncrypted(text) {
|
|
61
|
-
|
|
62
|
+
if (typeof text !== 'string' || !text.startsWith(ENCRYPTED_PREFIX)) {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
// Remove prefix and check that we have the expected structure (3 colon-separated parts)
|
|
66
|
+
const data = text.slice(ENCRYPTED_PREFIX.length);
|
|
67
|
+
const parts = data.split(':');
|
|
68
|
+
// Must have exactly 3 parts: iv, authTag, encryptedContent
|
|
69
|
+
if (parts.length !== 3) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
// Each part should be valid hex and have minimum length
|
|
73
|
+
// IV: 12 bytes = 24 hex chars, AuthTag: 16 bytes = 32 hex chars, Content: at least 1 byte = 2 hex chars
|
|
74
|
+
const [ivHex, authTagHex, encryptedHex] = parts;
|
|
75
|
+
return (ivHex.length === 24 && /^[0-9a-f]*$/i.test(ivHex) &&
|
|
76
|
+
authTagHex.length === 32 && /^[0-9a-f]*$/i.test(authTagHex) &&
|
|
77
|
+
encryptedHex.length > 0 && /^[0-9a-f]*$/i.test(encryptedHex));
|
|
62
78
|
}
|
|
@@ -31,7 +31,7 @@ export function FourOhFour(props) {
|
|
|
31
31
|
if (randomIndex !== null && imageURL /* cloudinaryURL */ !== '') {
|
|
32
32
|
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "fof-body-container", children: [_jsxs("h1", { className: "centered text-outline", children: ["404 - ", images[randomIndex].text] }), _jsx("div", { className: "centered-button", children: _jsx("a", { href: "/", target: "_self", rel: "noopener noreferrer", children: "Go Home" }) })] }), _jsx("div", { className: "fof-image-container", children: _jsx("div", { className: "fof-image-wrapper", children: _jsx(SmartImage, { src: imageURL,
|
|
33
33
|
// src={cloudinaryURL}
|
|
34
|
-
title: "Page Not Found - " + images[randomIndex].description, alt: "Page Not Found - " + images[randomIndex].description, variant: "nextjs", cloudinaryEnv: config?.cloudinary?.product_env ?? undefined, cloudinaryDomain: config?.cloudinary?.baseUrl ?? undefined, cloudinaryTransforms: config?.cloudinary?.transforms ?? undefined }) }) })] }));
|
|
34
|
+
aboveFold: true, title: "Page Not Found - " + images[randomIndex].description, alt: "Page Not Found - " + images[randomIndex].description, variant: "nextjs", cloudinaryEnv: config?.cloudinary?.product_env ?? undefined, cloudinaryDomain: config?.cloudinary?.baseUrl ?? undefined, cloudinaryTransforms: config?.cloudinary?.transforms ?? undefined }) }) })] }));
|
|
35
35
|
}
|
|
36
36
|
else {
|
|
37
37
|
return (_jsx(_Fragment, {}));
|
|
@@ -3,6 +3,19 @@
|
|
|
3
3
|
*
|
|
4
4
|
* A unified caching utility that supports Memory, LocalStorage, and SessionStorage.
|
|
5
5
|
* Includes TTL (Time-To-Live) support and automatic SSR fallback.
|
|
6
|
+
*
|
|
7
|
+
* ARCHITECTURE NOTE: The `domain` parameter is required to enforce clear namespace separation and
|
|
8
|
+
* provide future-proofing. While the library is currently deployed **per-domain** (each site gets
|
|
9
|
+
* its own isolated copy of this library), the domain parameter serves important purposes:
|
|
10
|
+
* 1. **Code Clarity**: Makes the multi-tenant intent explicit in code
|
|
11
|
+
* 2. **Future-Proofing**: If architecture changes to shared backends (Redis), isolation is built-in
|
|
12
|
+
* 3. **Safety**: Prevents accidental empty prefixes that could cause collisions
|
|
13
|
+
*
|
|
14
|
+
* Each domain runs in isolation:
|
|
15
|
+
* - Client-side: Uses window.location to determine domain (e.g., pixelvivid.com → "pixelvivid")
|
|
16
|
+
* - Server-side: Defaults to 'pixelated' (safe because server caches are in-memory per process)
|
|
17
|
+
* - Memory caches: Naturally isolated to their process, so multi-tenancy doesn't apply
|
|
18
|
+
* - Local/Session storage: Browser-based, inherently isolated by domain
|
|
6
19
|
*/
|
|
7
20
|
export class CacheManager {
|
|
8
21
|
memoryCache = new Map();
|
|
@@ -10,10 +23,14 @@ export class CacheManager {
|
|
|
10
23
|
mode;
|
|
11
24
|
prefix;
|
|
12
25
|
ttl;
|
|
13
|
-
constructor(options
|
|
26
|
+
constructor(options) {
|
|
14
27
|
this.mode = options.mode || 'memory';
|
|
15
|
-
this.prefix = options.prefix || 'pix_';
|
|
16
28
|
this.ttl = options.ttl || this.defaultTTL;
|
|
29
|
+
// Build prefix from domain + optional namespace
|
|
30
|
+
// domain + namespace pattern: "pixelvivid_cart_" or "sitehealth_analytics_"
|
|
31
|
+
this.prefix = options.namespace
|
|
32
|
+
? `${options.domain}_${options.namespace}_`
|
|
33
|
+
: `${options.domain}_`;
|
|
17
34
|
// Fallback to memory if browser storage is requested but unavailable (SSR/Node environment)
|
|
18
35
|
if (typeof window === 'undefined' && (this.mode === 'local' || this.mode === 'session')) {
|
|
19
36
|
this.mode = 'memory';
|
|
@@ -113,7 +113,7 @@ cloudinaryTransforms */ }) {
|
|
|
113
113
|
((variant === 'boxed' || variant === 'boxed grid') && boxShape ? " " + boxShape : "") +
|
|
114
114
|
(layout && variant !== 'split' ? " " + layout : "") +
|
|
115
115
|
(direction && layout !== 'vertical' ? " " + direction : "") +
|
|
116
|
-
(variant && (variant === 'boxed grid' || variant === 'grid') && gridColumns ? ` callout-grid-${gridColumns.left}-${gridColumns.right}` : ''), children: (direction === "right") ? _jsxs(_Fragment, { children: [body, image] }) : _jsxs(_Fragment, { children: [image, body] }) }));
|
|
116
|
+
(variant && (variant === 'boxed grid' || variant === 'grid') && gridColumns ? ` callout-grid-${gridColumns.left}-${gridColumns.right}` : ''), suppressHydrationWarning: true, children: (direction === "right") ? _jsxs(_Fragment, { children: [body, image] }) : _jsxs(_Fragment, { children: [image, body] }) }));
|
|
117
117
|
}
|
|
118
118
|
/* ========== CALLOUT HEADER ========== */
|
|
119
119
|
/**
|
|
@@ -188,28 +188,25 @@ export function DragHandler(props) {
|
|
|
188
188
|
}
|
|
189
189
|
}
|
|
190
190
|
;
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
}, [activeIndex]);
|
|
213
|
-
}
|
|
214
|
-
handleEventListeners(props.activeIndex);
|
|
191
|
+
useEffect(() => {
|
|
192
|
+
// const container = document.getElementById(classSelector);
|
|
193
|
+
// { passive: true } is needed for preventDefault to work on drag events
|
|
194
|
+
document.addEventListener('touchstart', dragStart, { capture: true, passive: false });
|
|
195
|
+
document.addEventListener('touchmove', draggable, { capture: true, passive: false });
|
|
196
|
+
document.addEventListener('touchend', dragEnd, { capture: true, passive: true });
|
|
197
|
+
document.addEventListener('mousedown', dragStart, { capture: true, passive: false });
|
|
198
|
+
document.addEventListener('mousemove', draggable, { capture: true, passive: false });
|
|
199
|
+
document.addEventListener('mouseup', dragEnd, { capture: true, passive: true });
|
|
200
|
+
document.addEventListener('transitionend', transitionEnd, { capture: true, passive: true });
|
|
201
|
+
return () => {
|
|
202
|
+
// { passive: true } is not needed to match and remove an event listener
|
|
203
|
+
document.removeEventListener('touchstart', dragStart, { capture: true });
|
|
204
|
+
document.removeEventListener('touchmove', draggable, { capture: true });
|
|
205
|
+
document.removeEventListener('touchend', dragEnd, { capture: true });
|
|
206
|
+
document.removeEventListener('mousedown', dragStart, { capture: true });
|
|
207
|
+
document.removeEventListener('mousemove', draggable, { capture: true });
|
|
208
|
+
document.removeEventListener('mouseup', dragEnd, { capture: true });
|
|
209
|
+
document.removeEventListener('transitionend', transitionEnd, { capture: true });
|
|
210
|
+
};
|
|
211
|
+
}, [props.activeIndex]);
|
|
215
212
|
}
|
|
@@ -115,10 +115,10 @@ export function Carousel(props) {
|
|
|
115
115
|
console.log('CarouselSimple: Dragging disabled');
|
|
116
116
|
}
|
|
117
117
|
if (props.cards && props.cards.length > 0) {
|
|
118
|
-
return (_jsxs("div", { className: "carousel-container", children: [_jsx("div", { className: "carousel-cards-container", children: props.cards.map((card, i) => (_jsx(CarouselCard, { index: i, cardIndex: cardIndex, cardLength: props.cards.length, link: card.link, linkTarget: card.linkTarget || '_self', image: card.image, imageAlt: card.imageAlt, imgFit: (props.imgFit || 'fill'), headerText: card.headerText, subHeaderText: card.subHeaderText, bodyText: card.bodyText }, i))) }), _jsxs("div", { className: "carousel-buttons", children: [_jsx(CarouselButton, { clickFunction: previousCard, glyph: '\u25C0' }), _jsx(CarouselButton, { clickFunction: stopTimer, glyph: '\u23F8' }), _jsx(CarouselButton, { clickFunction: nextCard, glyph: '\u25B6' })] })] }));
|
|
118
|
+
return (_jsxs("div", { className: "carousel-container", suppressHydrationWarning: true, children: [_jsx("div", { className: "carousel-cards-container", children: props.cards.map((card, i) => (_jsx(CarouselCard, { index: i, cardIndex: cardIndex, cardLength: props.cards.length, link: card.link, linkTarget: card.linkTarget || '_self', image: card.image, imageAlt: card.imageAlt, imgFit: (props.imgFit || 'fill'), headerText: card.headerText, subHeaderText: card.subHeaderText, bodyText: card.bodyText }, i))) }), _jsxs("div", { className: "carousel-buttons", children: [_jsx(CarouselButton, { clickFunction: previousCard, glyph: '\u25C0' }), _jsx(CarouselButton, { clickFunction: stopTimer, glyph: '\u23F8' }), _jsx(CarouselButton, { clickFunction: nextCard, glyph: '\u25B6' })] })] }));
|
|
119
119
|
}
|
|
120
120
|
else {
|
|
121
|
-
return (_jsx("div", { className: 'section-container', children: _jsx("div", { className: "carousel-container", children: _jsx(CarouselLoading, {}) }) }));
|
|
121
|
+
return (_jsx("div", { className: 'section-container', children: _jsx("div", { className: "carousel-container", suppressHydrationWarning: true, children: _jsx(CarouselLoading, {}) }) }));
|
|
122
122
|
}
|
|
123
123
|
}
|
|
124
124
|
/* ========== CAROUSEL CARD ========== */
|
|
@@ -139,7 +139,7 @@ function CarouselCard(props) {
|
|
|
139
139
|
}
|
|
140
140
|
const imgFit = props.imgFit ? "img" + capitalize(props.imgFit) : 'imgFill';
|
|
141
141
|
const config = usePixelatedConfig();
|
|
142
|
-
const cardBody = (_jsxs("div", { draggable: 'false', children: [(props.link) ? _jsx("div", { draggable: 'false', className: "carousel-card-link" }) : null, (props.image) ? _jsx("div", { draggable: 'false', className: "carousel-card-image", children: _jsx(SmartImage, { draggable: false, src: props.image, title: props?.imageAlt, alt: props?.imageAlt || "", className: imgFit, cloudinaryEnv: config?.cloudinary?.product_env ?? undefined, cloudinaryDomain: config?.cloudinary?.baseUrl ?? undefined, cloudinaryTransforms: config?.cloudinary?.transforms ?? undefined }) }) : null, (props.headerText) ? _jsx("div", { draggable: 'false', className: "carousel-card-header", children: _jsx("h3", { draggable: 'false', children: props.headerText }) }) : null, (props.subHeaderText) ? _jsx("div", { draggable: 'false', className: "carousel-card-subheader", children: _jsx("h4", { draggable: 'false', children: props.subHeaderText }) }) : null, (props.bodyText) ? _jsx("div", { draggable: 'false', className: "carousel-card-body", children: props.bodyText }) : null] }));
|
|
142
|
+
const cardBody = (_jsxs("div", { draggable: 'false', children: [(props.link) ? _jsx("div", { draggable: 'false', className: "carousel-card-link" }) : null, (props.image) ? _jsx("div", { draggable: 'false', className: "carousel-card-image", children: _jsx(SmartImage, { draggable: false, src: props.image, title: props?.imageAlt, alt: props?.imageAlt || "", className: imgFit, aboveFold: props?.index === 0 ? true : false, cloudinaryEnv: config?.cloudinary?.product_env ?? undefined, cloudinaryDomain: config?.cloudinary?.baseUrl ?? undefined, cloudinaryTransforms: config?.cloudinary?.transforms ?? undefined }) }) : null, (props.headerText) ? _jsx("div", { draggable: 'false', className: "carousel-card-header", children: _jsx("h3", { draggable: 'false', children: props.headerText }) }) : null, (props.subHeaderText) ? _jsx("div", { draggable: 'false', className: "carousel-card-subheader", children: _jsx("h4", { draggable: 'false', children: props.subHeaderText }) }) : null, (props.bodyText) ? _jsx("div", { draggable: 'false', className: "carousel-card-body", children: props.bodyText }) : null] }));
|
|
143
143
|
return (_jsx("div", { draggable: 'true', id: 'c-' + props.index, className: "carousel-card-wrapper", style: styles, children: _jsx("div", { draggable: 'false', className: "carousel-card", children: (props.link) ? _jsx("a", { draggable: 'false', href: props.link, target: props.linkTarget, children: cardBody }) : cardBody }) }));
|
|
144
144
|
}
|
|
145
145
|
// REMOVED PROPTYPE AS TYPESCRIPT TYPE COVERS THIS
|
|
@@ -58,5 +58,5 @@ export function CountUp({ id, pre = '', post = '', start, end, duration, decimal
|
|
|
58
58
|
}
|
|
59
59
|
}, intervalMs);
|
|
60
60
|
}, [isVisible]);
|
|
61
|
-
return (_jsx(_Fragment, { children: _jsxs("div", { ref: containerRef, className: "countup", children: [_jsx("span", { className: 'countup-pre', children: pre }), _jsx("span", { id: id, className: 'countup-counter', children: counter }), _jsx("span", { className: 'countup-post', children: post }), _jsx("p", { children: content })] }) }));
|
|
61
|
+
return (_jsx(_Fragment, { children: _jsxs("div", { ref: containerRef, className: "countup", suppressHydrationWarning: true, children: [_jsx("span", { className: 'countup-pre', children: pre }), _jsx("span", { id: id, className: 'countup-counter', children: counter }), _jsx("span", { className: 'countup-post', children: post }), _jsx("p", { children: content })] }) }));
|
|
62
62
|
}
|
|
@@ -99,6 +99,8 @@ export function observeIntersection(selector, callback, options = {}) {
|
|
|
99
99
|
* Check if an element is fully in the viewport
|
|
100
100
|
*/
|
|
101
101
|
export function isElementInViewport(element) {
|
|
102
|
+
if (!element)
|
|
103
|
+
return false;
|
|
102
104
|
const rect = element.getBoundingClientRect();
|
|
103
105
|
return (rect.top >= 0 &&
|
|
104
106
|
rect.left >= 0 &&
|
|
@@ -109,6 +111,8 @@ export function isElementInViewport(element) {
|
|
|
109
111
|
* Check if an element is partially in the viewport
|
|
110
112
|
*/
|
|
111
113
|
export function isElementPartiallyInViewport(element) {
|
|
114
|
+
if (!element)
|
|
115
|
+
return false;
|
|
112
116
|
const rect = element.getBoundingClientRect();
|
|
113
117
|
return (rect.top < (window.innerHeight || document.documentElement.clientHeight) &&
|
|
114
118
|
rect.left < (window.innerWidth || document.documentElement.clientWidth) &&
|
|
@@ -6,7 +6,7 @@ export function descriptionToKeywords(descriptionText, numKeywords = 5, customSt
|
|
|
6
6
|
// Define a default list of common English stop words
|
|
7
7
|
const defaultStopWords = new Set([
|
|
8
8
|
'a', 'an', 'and', 'are', 'as', 'at', 'be', 'but', 'by', 'for', 'if', 'in', 'into',
|
|
9
|
-
'is', 'it', 'no', 'not', 'of', 'on', 'or', 'such', 'that', 'the', 'their',
|
|
9
|
+
'is', 'it', 'no', 'not', 'of', 'on', 'or', 'over', 'such', 'that', 'the', 'their',
|
|
10
10
|
'then', 'there', 'these', 'they', 'this', 'to', 'was', 'will', 'with'
|
|
11
11
|
]);
|
|
12
12
|
const allStopWords = new Set([...defaultStopWords, ...customStopWords]);
|
|
@@ -128,5 +128,5 @@ export function generateMetaTags(props) {
|
|
|
128
128
|
const image_height = prop_image_height || siteInfo?.image_height;
|
|
129
129
|
const image_width = prop_image_width || siteInfo?.image_width;
|
|
130
130
|
const favicon = prop_favicon || siteInfo?.favicon;
|
|
131
|
-
return (_jsxs(_Fragment, { children: [_jsx("title", { children: title }), _jsx("meta", { charSet: "UTF-8" }), _jsx("meta", { httpEquiv: "content-type", content: "text/html; charset=UTF-8" }), _jsx("meta", { httpEquiv: 'Expires', content: '0' }), _jsx("meta", { httpEquiv: 'Pragma', content: 'no-cache' }), _jsx("meta", { httpEquiv: 'Cache-Control', content: 'no-cache' }), _jsx("meta", { name: "application-name", content: site_name }), _jsx("meta", { name: "author", content: site_name + ", " + email }), _jsx("meta", { name: 'copyright', content: site_name }), _jsx("meta", { name: "creator", content: site_name }), _jsx("meta", { name: "description", content: description }), _jsx("meta", { name: "keywords", content: keywords }), _jsx("meta", { name: 'language', content: 'EN' }), _jsx("meta", { name: 'owner', content: site_name }), _jsx("meta", { name: "publisher", content: site_name }), _jsx("meta", { name: 'rating', content: 'General' }), _jsx("meta", { name: 'reply-to', content: email }), _jsx("meta", { name: "robots", content: "index, follow" }), _jsx("meta", { name: 'url', content: url }), _jsx("meta", { name: "viewport", content: "width=device-width, initial-scale=1.0, shrink-to-fit=no" }), _jsx("meta", { property: "og:description", content: description }), _jsx("meta", { property: 'og:email', content: email }), _jsx("meta", { property: "og:image", content: image }), _jsx("meta", { property: "og:image:height", content: image_height != null ? String(image_height) : undefined }), _jsx("meta", { property: "og:image:width", content: image_width != null ? String(image_width) : undefined }), _jsx("meta", { property: "og:locale", content: "en_US" }), _jsx("meta", { property: "og:site_name", content: site_name }), _jsx("meta", { property: "og:title", content: title }), _jsx("meta", { property: "og:type", content: "website" }), _jsx("meta", { property: "og:url", content: url }), _jsx("meta", { itemProp: "name", content: site_name }), _jsx("meta", { itemProp: "url", content: url }), _jsx("meta", { itemProp: "description", content: description }), _jsx("meta", { itemProp: "thumbnailUrl", content: image }), _jsx("meta", { property: "twitter:domain", content: newOrigin }), _jsx("meta", { property: "twitter:url", content: url }), _jsx("meta", { name: "twitter:card", content: "summary_large_image" }), _jsx("meta", { name: "twitter:creator", content: site_name }), _jsx("meta", { name: "twitter:description", content: description }), _jsx("meta", { name: "twitter:image", content: image }), _jsx("meta", { name: "twitter:image:height", content: image_height != null ? String(image_height) : undefined }), _jsx("meta", { name: "twitter:image:width", content: image_width != null ? String(image_width) : undefined }), _jsx("meta", { name: "twitter:title", content: title }), _jsx("link", { rel: "author", href: "humans.txt" }), _jsx("link", { rel: "canonical", href: url }), _jsx("link", { rel: "icon", type: "image/x-icon", href: favicon }), _jsx("link", { rel: "shortcut icon", type: "image/x-icon", href: favicon }), _jsx("link", { rel: "manifest", href: "/manifest.webmanifest" }), _jsx("link", { rel: "preconnect", href: "https://images.ctfassets.net/" }), _jsx("link", { rel: "preconnect", href: "https://res.cloudinary.com/" }), _jsx("link", { rel: "preconnect", href: "https://farm2.static.flickr.com" }), _jsx("link", { rel: "preconnect", href: "https://farm6.static.flickr.com" }), _jsx("link", { rel: "preconnect", href: "https://farm8.static.flickr.com" }), _jsx("link", { rel: "preconnect", href: "https://farm66.static.flickr.com" })] }));
|
|
131
|
+
return (_jsxs(_Fragment, { children: [_jsx("title", { children: title }), _jsx("meta", { charSet: "UTF-8" }), _jsx("meta", { httpEquiv: "content-type", content: "text/html; charset=UTF-8" }), _jsx("meta", { httpEquiv: 'Expires', content: '0' }), _jsx("meta", { httpEquiv: 'Pragma', content: 'no-cache' }), _jsx("meta", { httpEquiv: 'Cache-Control', content: 'no-cache' }), _jsx("meta", { name: "application-name", content: site_name }), _jsx("meta", { name: "author", content: site_name + ", " + email }), _jsx("meta", { name: 'copyright', content: site_name }), _jsx("meta", { name: "creator", content: site_name }), _jsx("meta", { name: "description", content: description }), _jsx("meta", { name: "keywords", content: keywords }), _jsx("meta", { name: 'language', content: 'EN' }), _jsx("meta", { name: 'owner', content: site_name }), _jsx("meta", { name: "publisher", content: site_name }), _jsx("meta", { name: 'rating', content: 'General' }), _jsx("meta", { name: 'reply-to', content: email }), _jsx("meta", { name: "robots", content: "index, follow" }), _jsx("meta", { name: 'url', content: url }), _jsx("meta", { name: "viewport", content: "width=device-width, initial-scale=1.0, shrink-to-fit=no" }), _jsx("meta", { property: "og:description", content: description }), _jsx("meta", { property: 'og:email', content: email }), _jsx("meta", { property: "og:image", content: image }), _jsx("meta", { property: "og:image:height", content: image_height != null ? String(image_height) : undefined }), _jsx("meta", { property: "og:image:width", content: image_width != null ? String(image_width) : undefined }), _jsx("meta", { property: "og:locale", content: "en_US" }), _jsx("meta", { property: "og:site_name", content: site_name }), _jsx("meta", { property: "og:title", content: title }), _jsx("meta", { property: "og:type", content: "website" }), _jsx("meta", { property: "og:url", content: url }), _jsx("meta", { itemProp: "name", content: site_name }), _jsx("meta", { itemProp: "url", content: url }), _jsx("meta", { itemProp: "description", content: description }), _jsx("meta", { itemProp: "thumbnailUrl", content: image }), _jsx("meta", { property: "twitter:domain", content: newOrigin }), _jsx("meta", { property: "twitter:url", content: url }), _jsx("meta", { name: "twitter:card", content: "summary_large_image" }), _jsx("meta", { name: "twitter:creator", content: site_name }), _jsx("meta", { name: "twitter:description", content: description }), _jsx("meta", { name: "twitter:image", content: image }), _jsx("meta", { name: "twitter:image:height", content: image_height != null ? String(image_height) : undefined }), _jsx("meta", { name: "twitter:image:width", content: image_width != null ? String(image_width) : undefined }), _jsx("meta", { name: "twitter:title", content: title }), _jsx("link", { rel: "author", fetchPriority: "high", href: "humans.txt" }), _jsx("link", { rel: "canonical", fetchPriority: "high", href: url }), _jsx("link", { rel: "icon", fetchPriority: "high", type: "image/x-icon", href: favicon }), _jsx("link", { rel: "shortcut icon", fetchPriority: "high", type: "image/x-icon", href: favicon }), _jsx("link", { rel: "manifest", fetchPriority: "high", href: "/manifest.webmanifest" }), _jsx("link", { rel: "preconnect", fetchPriority: "high", href: "https://images.ctfassets.net/" }), _jsx("link", { rel: "preconnect", fetchPriority: "high", href: "https://res.cloudinary.com/" }), _jsx("link", { rel: "preconnect", fetchPriority: "high", href: "https://farm2.static.flickr.com" }), _jsx("link", { rel: "preconnect", fetchPriority: "high", href: "https://farm6.static.flickr.com" }), _jsx("link", { rel: "preconnect", fetchPriority: "high", href: "https://farm8.static.flickr.com" }), _jsx("link", { rel: "preconnect", fetchPriority: "high", href: "https://farm66.static.flickr.com" })] }));
|
|
132
132
|
}
|
|
@@ -41,14 +41,14 @@ export function handlePixelatedProxy(req) {
|
|
|
41
41
|
response.headers.set("Permissions-Policy", "camera=(), microphone=(), geolocation=(), interest-cohort=()");
|
|
42
42
|
// Content Security Policy (CSP)
|
|
43
43
|
// Includes all discovered domains in the workspace: HubSpot, Gravatar, Flickr, Contentful, Cloudinary, eBay, and Google Analytics + Search.
|
|
44
|
-
const scriptSrc = "'self' 'unsafe-inline' 'unsafe-eval' https://va.vercel-scripts.com https://*.googletagmanager.com https://*.hs-scripts.com https://*.hs-analytics.net https://*.hsforms.net https://*.hscollectedforms.net https://*.hs-banner.com https://*.google.com https://*.doubleclick.net https://*.googleadservices.com https://*.adtrafficquality.google https://*.hsappstatic.net https://assets.calendly.com https://cdn.jsdelivr.net https://www.paypal.com https://www.paypalobjects.com";
|
|
44
|
+
const scriptSrc = "'self' 'unsafe-inline' 'unsafe-eval' https://va.vercel-scripts.com https://*.googletagmanager.com https://*.hs-scripts.com https://*.hs-analytics.net https://*.hsforms.net https://*.hscollectedforms.net https://*.hs-banner.com https://*.google.com https://*.doubleclick.net https://*.googleadservices.com https://*.adtrafficquality.google https://*.hsappstatic.net https://assets.calendly.com https://cdn.jsdelivr.net https://www.paypal.com https://www.paypalobjects.com https://cdn.curator.io https://connect.facebook.net";
|
|
45
45
|
const csp = [
|
|
46
46
|
"default-src 'self'",
|
|
47
47
|
`script-src ${scriptSrc}`,
|
|
48
48
|
`script-src-elem ${scriptSrc}`,
|
|
49
49
|
"connect-src 'self' https: https://*.hubspot.com https://proxy.pixelated.tech https://sendmail.pixelated.tech https://*.google-analytics.com https://*.analytics.google.com https://cdn.jsdelivr.net",
|
|
50
50
|
"img-src 'self' data: https: https://*.gravatar.com https://*.staticflickr.com https://*.ctfassets.net https://res.cloudinary.com https://*.ebayimg.com",
|
|
51
|
-
"style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://*.google.com https://www.paypalobjects.com",
|
|
51
|
+
"style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://*.google.com https://www.paypalobjects.com https://cdn.curator.io",
|
|
52
52
|
"font-src 'self' data: https://fonts.gstatic.com",
|
|
53
53
|
"media-src 'self' https://*.ctfassets.net",
|
|
54
54
|
"frame-src 'self' https://*.hubspot.com https://*.googletagmanager.com https://*.adtrafficquality.google https://*.google.com https://calendly.com https://*.calendly.com https://*.hsforms.net https://www.paypal.com https://www.paypalobjects.com",
|
|
@@ -166,8 +166,8 @@ PageSectionHeader.propTypes = {
|
|
|
166
166
|
export function PageSectionHeader({ title, url }) {
|
|
167
167
|
const calloutTarget = url && url.substring(0, 4).toLowerCase() === 'http' ? '_blank' : '_self';
|
|
168
168
|
return (_jsx(_Fragment, { children: url
|
|
169
|
-
? _jsx("a", { href: url, target: calloutTarget, rel: "noopener noreferrer", children: _jsx("h2", { className: "page-section-header", children: title }) })
|
|
170
|
-
: _jsx("h2", { className: "page-section-header", children: title }) }));
|
|
169
|
+
? _jsx("a", { href: url, target: calloutTarget, rel: "noopener noreferrer", children: _jsx("h2", { className: "page-section-header", suppressHydrationWarning: true, children: title }) })
|
|
170
|
+
: _jsx("h2", { className: "page-section-header", suppressHydrationWarning: true, children: title }) }));
|
|
171
171
|
}
|
|
172
172
|
;
|
|
173
173
|
// ========== PAGE SECTION BACKGROUND IMAGE ==========
|
|
@@ -240,10 +240,7 @@ export function PageGridItem({ id, className, columnSpan, rowSpan, columnStart,
|
|
|
240
240
|
...(alignSelf && { alignSelf }),
|
|
241
241
|
...(justifySelf && { justifySelf }),
|
|
242
242
|
};
|
|
243
|
-
return (
|
|
244
|
-
/* THIS IS AN OLD STYLE */
|
|
245
|
-
/* <div className={"grid-item" + */
|
|
246
|
-
_jsx("div", { className: "grid-item" +
|
|
243
|
+
return (_jsx("div", { className: "grid-item" +
|
|
247
244
|
(className ? ` ${className}` : '') +
|
|
248
245
|
(columnStart && columnSpan && !columnEnd ? ` grid-s${columnStart}-w${columnSpan}` : '') +
|
|
249
246
|
(columnStart && columnEnd && !columnSpan ? ` grid-s${columnStart}-e${columnEnd}` : ''), id: (id) ? id : undefined, style: itemStyle, children: children }));
|
|
@@ -6,6 +6,7 @@ import { getContentfulFieldValues, getContentfulAssets } from "../integrations/c
|
|
|
6
6
|
import { getEbayAppToken, getEbayItemsSearch } from "../shoppingcart/ebay.functions";
|
|
7
7
|
import { getFullPixelatedConfig } from '../config/config';
|
|
8
8
|
import { CacheManager } from '../general/cache-manager';
|
|
9
|
+
import { getDomain } from './utilities';
|
|
9
10
|
/**
|
|
10
11
|
* Helper to construct an origin string from a Next-like headers() object or plain values.
|
|
11
12
|
* Accepts an object with `get(key)` method, or `undefined` and falls back to localhost origin.
|
|
@@ -438,7 +439,7 @@ export async function createEbayItemURLs(origin) {
|
|
|
438
439
|
}
|
|
439
440
|
const SITEMAP_TTL = 24 * 60 * 60 * 1000; // one day
|
|
440
441
|
const EBAY_SITE_SITEMAP_KEY = 'ebay_sitemap_items';
|
|
441
|
-
const ebaySitemapCache = new CacheManager({ mode: 'memory',
|
|
442
|
+
const ebaySitemapCache = new CacheManager({ mode: 'memory', domain: getDomain(), namespace: 'ebaySitemap', ttl: SITEMAP_TTL });
|
|
442
443
|
function getEbayCacheTTL(configTTL) {
|
|
443
444
|
if (typeof configTTL === 'number' && configTTL > 0) {
|
|
444
445
|
return configTTL;
|
|
@@ -207,7 +207,7 @@ export function SmartImage(props) {
|
|
|
207
207
|
delete newProps.cloudinaryTransforms;
|
|
208
208
|
if (variant !== 'img') {
|
|
209
209
|
try {
|
|
210
|
-
return (_jsx(Image, { ...newProps, src: newProps.src, alt: newProps.alt, onError: handleError }));
|
|
210
|
+
return (_jsx(Image, { ...newProps, src: newProps.src, alt: newProps.alt, onError: handleError, suppressHydrationWarning: true }));
|
|
211
211
|
}
|
|
212
212
|
catch (e) {
|
|
213
213
|
console.warn(`SmartImage: Next.js Image threw exception for "${props.src}", falling back to plain img`, e);
|
|
@@ -216,7 +216,5 @@ export function SmartImage(props) {
|
|
|
216
216
|
}
|
|
217
217
|
}
|
|
218
218
|
/* ===== IMG VARIANT ===== */
|
|
219
|
-
return (
|
|
220
|
-
/* eslint-disable-next-line pixelated/no-raw-img */
|
|
221
|
-
_jsx("img", { ...newProps, ref: imgRef, alt: newProps.alt }));
|
|
219
|
+
return (_jsx("img", { ...newProps, ref: imgRef, alt: newProps.alt, suppressHydrationWarning: true }));
|
|
222
220
|
}
|
|
@@ -35,7 +35,7 @@ export function StyleGuideUI(props) {
|
|
|
35
35
|
justify-content: center;
|
|
36
36
|
display: flex;
|
|
37
37
|
}
|
|
38
|
-
` }), _jsxs(PageSection, { columns: 1, maxWidth: "1024px", padding: "20px", id: "fonts-section", children: [_jsxs("h1", { children: ["H1 - ", primaryHeaderFont, " font"] }), _jsxs("h2", { children: ["H2 - ", primaryHeaderFont, " font"] }), _jsxs("h3", { children: ["H3 - ", primaryHeaderFont, " font"] }), _jsxs("h4", { children: ["H4 - ", primaryHeaderFont, " font"] }), _jsxs("h5", { children: ["H5 - ", primaryHeaderFont, " font"] }), _jsxs("h6", { children: ["H6 - ", primaryHeaderFont, " font"] }), _jsxs("p", { children: [primaryBodyFont, " font. This is a paragraph of text to demonstrate the body font style. "] }), _jsxs("p", { children: [primaryBodyFont, " font. The quick brown fox jumps over the lazy dog. "] }), _jsxs("p", { children: [primaryBodyFont, " font. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."] })] }), _jsxs(PageSection, { columns: 1, maxWidth: "1024px", padding: "20px", id: "fonts-section", children: [_jsx("h2", { children: "Information Architecture" }), _jsx("ul", { children: flattenRoutes(routes).map((r, index) => {
|
|
38
|
+
` }), _jsxs(PageSection, { columns: 1, maxWidth: "1024px", padding: "20px", id: "fonts-section", children: [_jsxs("h1", { suppressHydrationWarning: true, children: ["H1 - ", primaryHeaderFont, " font"] }), _jsxs("h2", { suppressHydrationWarning: true, children: ["H2 - ", primaryHeaderFont, " font"] }), _jsxs("h3", { suppressHydrationWarning: true, children: ["H3 - ", primaryHeaderFont, " font"] }), _jsxs("h4", { suppressHydrationWarning: true, children: ["H4 - ", primaryHeaderFont, " font"] }), _jsxs("h5", { suppressHydrationWarning: true, children: ["H5 - ", primaryHeaderFont, " font"] }), _jsxs("h6", { suppressHydrationWarning: true, children: ["H6 - ", primaryHeaderFont, " font"] }), _jsxs("p", { suppressHydrationWarning: true, children: [primaryBodyFont, " font. This is a paragraph of text to demonstrate the body font style. "] }), _jsxs("p", { suppressHydrationWarning: true, children: [primaryBodyFont, " font. The quick brown fox jumps over the lazy dog. "] }), _jsxs("p", { suppressHydrationWarning: true, children: [primaryBodyFont, " font. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."] })] }), _jsxs(PageSection, { columns: 1, maxWidth: "1024px", padding: "20px", id: "fonts-section", children: [_jsx("h2", { children: "Information Architecture" }), _jsx("ul", { children: flattenRoutes(routes).map((r, index) => {
|
|
39
39
|
return _jsxs("li", { children: [r.name, " - ", r.path] }, index);
|
|
40
40
|
}) })] })] }));
|
|
41
41
|
}
|
|
@@ -42,7 +42,7 @@ Tiles.propTypes = {
|
|
|
42
42
|
export function Tiles(props) {
|
|
43
43
|
const rowCount = props.rowCount ?? 2;
|
|
44
44
|
if (props.cards && props.cards.length > 0) {
|
|
45
|
-
return (_jsx("div", { className: "tiles-container", children: _jsx("div", { className: `tile-container row-${rowCount}col`, children: props.cards.map((card, i) => (_jsx("div", { className: "grid-item", children: _jsx(Tile, { index: card.index ?? i, cardLength: card.cardLength ?? props.cards.length, link: card.link, image: card.image, imageAlt: card.imageAlt, bodyText: card.bodyText, imgClick: props.imgClick, variant: (props.variant ?? "overlay") }) }, i))) }) }));
|
|
45
|
+
return (_jsx("div", { className: "tiles-container", children: _jsx("div", { className: `tile-container row-${rowCount}col`, suppressHydrationWarning: true, children: props.cards.map((card, i) => (_jsx("div", { className: "grid-item", children: _jsx(Tile, { index: card.index ?? i, cardLength: card.cardLength ?? props.cards.length, link: card.link, image: card.image, imageAlt: card.imageAlt, bodyText: card.bodyText, imgClick: props.imgClick, variant: (props.variant ?? "overlay") }) }, i))) }) }));
|
|
46
46
|
}
|
|
47
47
|
else {
|
|
48
48
|
return (_jsx(Loading, {}));
|
|
@@ -85,7 +85,7 @@ function Tile(props) {
|
|
|
85
85
|
const captionText = (props.bodyText && props.bodyText.length > 0) ? props.bodyText : (props.imageAlt ?? "");
|
|
86
86
|
const tileBody = _jsxs("div", { className: "tile-image" + (imgClick ? " clickable" : ""), children: [_jsx(SmartImage, { src: props.image, title: props?.imageAlt ?? undefined, alt: props?.imageAlt ?? "", onClick: imgClick ? (event) => imgClick(event, props.image) : undefined, cloudinaryEnv: config?.cloudinary?.product_env ?? undefined }), _jsx("div", { className: "tile-image-overlay", children: _jsxs("div", { className: "tile-image-overlay-text", children: [_jsx("div", { className: "tile-image-overlay-title", children: props.imageAlt }), _jsx("div", { className: "tile-image-overlay-body", children: props.bodyText })] }) })] });
|
|
87
87
|
const rootClass = `tile${(props.variant) ? ' ' + props.variant : ''}`;
|
|
88
|
-
return (_jsx("div", { className: rootClass, id: 'tile-' + props.index, children: props.link ?
|
|
88
|
+
return (_jsx("div", { className: rootClass, id: 'tile-' + props.index, suppressHydrationWarning: true, children: props.link ?
|
|
89
89
|
_jsx("a", { href: props.link, className: "tile-link", children: tileBody })
|
|
90
90
|
:
|
|
91
91
|
tileBody }));
|
|
@@ -47,5 +47,5 @@ TimelineItem.propTypes = {
|
|
|
47
47
|
};
|
|
48
48
|
export default function TimelineItem(props) {
|
|
49
49
|
const config = usePixelatedConfig();
|
|
50
|
-
return (_jsx("div", { className: "timeline-container timeline-" + props.direction, children: _jsx("div", { className: "timeline-content", children: _jsxs("div", { className: "row-3col", children: [_jsx("div", { className: "grid-s1-e2", children: _jsx(SmartImage, { src: props.image || "", title: props.title, alt: props.title, cloudinaryEnv: config?.cloudinary?.product_env ?? undefined }) }), _jsxs("div", { className: "grid-s2-e4", children: [_jsx("h2", { children: props.title }), _jsx("p", { children: props.content })] })] }) }) }));
|
|
50
|
+
return (_jsx("div", { className: "timeline-container timeline-" + props.direction, suppressHydrationWarning: true, children: _jsx("div", { className: "timeline-content", children: _jsxs("div", { className: "row-3col", children: [_jsx("div", { className: "grid-s1-e2", children: _jsx(SmartImage, { src: props.image || "", title: props.title, alt: props.title, cloudinaryEnv: config?.cloudinary?.product_env ?? undefined }) }), _jsxs("div", { className: "grid-s2-e4", children: [_jsx("h2", { children: props.title }), _jsx("p", { children: props.content })] })] }) }) }));
|
|
51
51
|
}
|
|
@@ -64,6 +64,74 @@ Array.prototype.contains = function(obj) {
|
|
|
64
64
|
return this.indexOf(obj) > -1;
|
|
65
65
|
};
|
|
66
66
|
*/
|
|
67
|
+
/**
|
|
68
|
+
* Get the domain name to use as a key component for CacheManager.
|
|
69
|
+
* Safe to call in browser contexts. For server-side, use getDomainFromHeaders() instead.
|
|
70
|
+
*
|
|
71
|
+
* Extracts the domain name from the current hostname to use as a cache/storage prefix.
|
|
72
|
+
* This ensures multi-tenant applications don't have key collisions across different domain instances.
|
|
73
|
+
*
|
|
74
|
+
* @returns Domain name suitable for multi-tenant cache isolation (lowercase, no special characters)
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* const domain = getDomain();
|
|
78
|
+
* const cache = new CacheManager({
|
|
79
|
+
* mode: 'local',
|
|
80
|
+
* domain,
|
|
81
|
+
* namespace: 'checkout'
|
|
82
|
+
* });
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* // In different environments:
|
|
86
|
+
* // www.pixelvivid.com → "pixelvivid"
|
|
87
|
+
* // manningmetalworks.com → "manningmetalworks"
|
|
88
|
+
* // localhost → "pixelated" (development)
|
|
89
|
+
*/
|
|
90
|
+
export function getDomain() {
|
|
91
|
+
// Browser environment
|
|
92
|
+
if (typeof window !== 'undefined' && window.location?.hostname) {
|
|
93
|
+
return extractDomainName(window.location.hostname);
|
|
94
|
+
}
|
|
95
|
+
// SSR/Node environment - return safe fallback
|
|
96
|
+
// Library is deployed per-domain, so no actual multi-tenancy at library level
|
|
97
|
+
// Each domain runs its own isolated copy of this library
|
|
98
|
+
return 'pixelated';
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Extract the domain name from a hostname string.
|
|
102
|
+
* Handles www prefixes and multi-level TLDs.
|
|
103
|
+
*
|
|
104
|
+
* @param hostname - The hostname (e.g., "www.example.com" or "example.com")
|
|
105
|
+
* @returns The domain name without www or TLD (lowercase)
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* extractDomainName('www.pixelvivid.com') // → "pixelvivid"
|
|
109
|
+
* extractDomainName('manningmetalworks.com') // → "manningmetalworks"
|
|
110
|
+
* extractDomainName('localhost') // → "pixelated"
|
|
111
|
+
*/
|
|
112
|
+
export function extractDomainName(hostname) {
|
|
113
|
+
if (!hostname)
|
|
114
|
+
return 'pixelated';
|
|
115
|
+
// Normalize: lowercase, trim whitespace
|
|
116
|
+
const normalized = hostname.toLowerCase().trim();
|
|
117
|
+
// Handle localhost / 127.0.0.1 - use development prefix
|
|
118
|
+
if (normalized === 'localhost' || normalized === '127.0.0.1' || normalized.startsWith('localhost:')) {
|
|
119
|
+
return 'pixelated';
|
|
120
|
+
}
|
|
121
|
+
// Split by dots
|
|
122
|
+
const parts = normalized.split('.');
|
|
123
|
+
// Single label (rare but possible in development)
|
|
124
|
+
if (parts.length === 1) {
|
|
125
|
+
return parts[0];
|
|
126
|
+
}
|
|
127
|
+
// Two labels: domain.com → domain
|
|
128
|
+
if (parts.length === 2) {
|
|
129
|
+
return parts[0];
|
|
130
|
+
}
|
|
131
|
+
// Multiple labels: www.domain.com or subdomain.domain.com → domain
|
|
132
|
+
// Take the second-to-last part (the domain before the TLD)
|
|
133
|
+
return parts[parts.length - 2];
|
|
134
|
+
}
|
|
67
135
|
export function attributeMap(oldAttribute) {
|
|
68
136
|
// https://reactjs.org/docs/dom-elements.html
|
|
69
137
|
const attributes = {
|
|
@@ -114,10 +114,10 @@ getContentfulContentType.propTypes = {
|
|
|
114
114
|
/** Contentful API configuration */
|
|
115
115
|
apiProps: PropTypes.shape({
|
|
116
116
|
proxyURL: PropTypes.string,
|
|
117
|
-
base_url: PropTypes.string
|
|
118
|
-
space_id: PropTypes.string
|
|
119
|
-
environment: PropTypes.string
|
|
120
|
-
access_token: PropTypes.string
|
|
117
|
+
base_url: PropTypes.string,
|
|
118
|
+
space_id: PropTypes.string,
|
|
119
|
+
environment: PropTypes.string,
|
|
120
|
+
access_token: PropTypes.string,
|
|
121
121
|
}).isRequired,
|
|
122
122
|
/** Content type ID to retrieve */
|
|
123
123
|
contentType: PropTypes.string.isRequired,
|
|
@@ -142,10 +142,10 @@ getContentfulEntryByEntryID.propTypes = {
|
|
|
142
142
|
/** Contentful API configuration */
|
|
143
143
|
apiProps: PropTypes.shape({
|
|
144
144
|
proxyURL: PropTypes.string,
|
|
145
|
-
base_url: PropTypes.string
|
|
146
|
-
space_id: PropTypes.string
|
|
147
|
-
environment: PropTypes.string
|
|
148
|
-
delivery_access_token: PropTypes.string
|
|
145
|
+
base_url: PropTypes.string,
|
|
146
|
+
space_id: PropTypes.string,
|
|
147
|
+
environment: PropTypes.string,
|
|
148
|
+
delivery_access_token: PropTypes.string,
|
|
149
149
|
}).isRequired,
|
|
150
150
|
/** Target entry ID */
|
|
151
151
|
entry_id: PropTypes.string.isRequired,
|
|
@@ -239,10 +239,10 @@ getContentfulAssets.propTypes = {
|
|
|
239
239
|
/** Contentful API configuration */
|
|
240
240
|
apiProps: PropTypes.shape({
|
|
241
241
|
proxyURL: PropTypes.string,
|
|
242
|
-
base_url: PropTypes.string
|
|
243
|
-
space_id: PropTypes.string
|
|
244
|
-
environment: PropTypes.string
|
|
245
|
-
access_token: PropTypes.string
|
|
242
|
+
base_url: PropTypes.string,
|
|
243
|
+
space_id: PropTypes.string,
|
|
244
|
+
environment: PropTypes.string,
|
|
245
|
+
access_token: PropTypes.string,
|
|
246
246
|
}).isRequired,
|
|
247
247
|
};
|
|
248
248
|
export async function getContentfulAssets(props) {
|
|
@@ -263,10 +263,10 @@ getContentfulAssetURLs.propTypes = {
|
|
|
263
263
|
/** Contentful API configuration */
|
|
264
264
|
apiProps: PropTypes.shape({
|
|
265
265
|
proxyURL: PropTypes.string,
|
|
266
|
-
base_url: PropTypes.string
|
|
267
|
-
space_id: PropTypes.string
|
|
268
|
-
environment: PropTypes.string
|
|
269
|
-
access_token: PropTypes.string
|
|
266
|
+
base_url: PropTypes.string,
|
|
267
|
+
space_id: PropTypes.string,
|
|
268
|
+
environment: PropTypes.string,
|
|
269
|
+
access_token: PropTypes.string,
|
|
270
270
|
}).isRequired,
|
|
271
271
|
};
|
|
272
272
|
export async function getContentfulAssetURLs(props) {
|
|
@@ -13,15 +13,6 @@ import { SmartImage } from "../general/smartimage";
|
|
|
13
13
|
import "../../css/pixelated.grid.scss";
|
|
14
14
|
import "./contentful.items.css";
|
|
15
15
|
const debug = false;
|
|
16
|
-
let ContentfulApiProps = {
|
|
17
|
-
proxyURL: 'https://proxy.pixelated.tech/prod/proxy?url=',
|
|
18
|
-
base_url: "https://cdn.contentful.com",
|
|
19
|
-
space_id: "soi9w77t7027",
|
|
20
|
-
environment: "master",
|
|
21
|
-
management_access_token: "",
|
|
22
|
-
delivery_access_token: "muY9LfpCt4qoXosDsnRkkoH3DAVVuUFEuB0WRKRdBUM",
|
|
23
|
-
preview_access_token: "",
|
|
24
|
-
};
|
|
25
16
|
const contentfulContentType = "item";
|
|
26
17
|
/* ========== CONTENTFUL ITEMS PAGE ========== */
|
|
27
18
|
/**
|
|
@@ -50,7 +41,7 @@ export function ContentfulItems(props) {
|
|
|
50
41
|
if ((providerContentful as any).proxyURL) localContentfulApiProps.proxyURL = (providerContentful as any).proxyURL;
|
|
51
42
|
} */
|
|
52
43
|
const providerContentfulApiProps = usePixelatedConfig()?.contentful;
|
|
53
|
-
const mergedApiProps = { ...
|
|
44
|
+
const mergedApiProps = { ...providerContentfulApiProps, ...props.apiProps };
|
|
54
45
|
const [apiProps] = useState(mergedApiProps);
|
|
55
46
|
/**
|
|
56
47
|
* paintItems — Convert Contentful API items and assets into rendered list nodes.
|
|
@@ -204,7 +195,7 @@ export function ContentfulItemDetail(props) {
|
|
|
204
195
|
const [assets, setAssets] = useState({});
|
|
205
196
|
const [cards, setCards] = useState([]);
|
|
206
197
|
const providerContentfulApiProps = usePixelatedConfig()?.contentful;
|
|
207
|
-
const [apiProps] = useState({ ...
|
|
198
|
+
const [apiProps] = useState({ ...providerContentfulApiProps, ...props.apiProps });
|
|
208
199
|
useEffect(() => {
|
|
209
200
|
if (debug)
|
|
210
201
|
console.log("Running useEffect");
|