@pixelated-tech/components 3.4.0 → 3.4.2
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/deploy/deployment.integration.js +15 -22
- package/dist/components/admin/site-health/seo-constants.js +14 -0
- package/dist/components/admin/site-health/site-health-cloudwatch.integration.js +142 -0
- package/dist/components/admin/site-health/site-health-cloudwatch.js +44 -0
- package/dist/components/admin/site-health/site-health-on-site-seo.integration.js +119 -28
- package/dist/components/cms/pixelated.linkedin1.js +1 -19
- package/dist/components/shoppingcart/shoppingcart.components.js +2 -1
- package/dist/components/utilities/functions.js +5 -2
- package/dist/index.js +2 -0
- package/dist/index.server.js +2 -0
- package/dist/types/components/admin/site-health/seo-constants.d.ts +8 -0
- package/dist/types/components/admin/site-health/seo-constants.d.ts.map +1 -0
- package/dist/types/components/admin/site-health/site-health-cloudwatch.d.ts +8 -0
- package/dist/types/components/admin/site-health/site-health-cloudwatch.d.ts.map +1 -0
- package/dist/types/components/admin/site-health/site-health-cloudwatch.integration.d.ts +25 -0
- package/dist/types/components/admin/site-health/site-health-cloudwatch.integration.d.ts.map +1 -0
- package/dist/types/components/admin/site-health/site-health-on-site-seo.integration.d.ts.map +1 -1
- package/dist/types/components/cms/pixelated.linkedin1.d.ts.map +1 -1
- package/dist/types/components/utilities/functions.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.server.d.ts +2 -0
- package/dist/types/stories/carousel/tiles.stories.d.ts.map +1 -1
- package/package.json +2 -1
|
@@ -23,22 +23,15 @@ export async function executeDeployment(request, siteConfig, isLocalExecution =
|
|
|
23
23
|
async function executeScript(siteName, versionType, commitMessage, environments, localPath, remote) {
|
|
24
24
|
const sourceBranch = 'dev'; // Always deploy from dev branch
|
|
25
25
|
try {
|
|
26
|
-
// Change to the site directory
|
|
27
|
-
process.chdir(localPath);
|
|
28
26
|
// Get current branch and ensure we're on dev
|
|
29
|
-
const { stdout: currentBranch } = await execAsync('git branch --show-current');
|
|
27
|
+
const { stdout: currentBranch } = await execAsync('git branch --show-current', { cwd: localPath });
|
|
30
28
|
if (currentBranch.trim() !== sourceBranch) {
|
|
31
29
|
throw new Error(`Must be on ${sourceBranch} branch to deploy. Current branch: ${currentBranch.trim()}`);
|
|
32
30
|
}
|
|
33
|
-
// Check for uncommitted changes
|
|
34
|
-
const { stdout: status } = await execAsync('git status --porcelain');
|
|
35
|
-
if (status.trim()) {
|
|
36
|
-
throw new Error('There are uncommitted changes. Please commit or stash them before deploying.');
|
|
37
|
-
}
|
|
38
31
|
// Pull latest changes
|
|
39
|
-
await execAsync(
|
|
32
|
+
await execAsync(`git pull ${remote} dev`, { cwd: localPath });
|
|
40
33
|
// Run prep commands
|
|
41
|
-
const prepResult = await runPrepCommands(siteName, versionType, commitMessage);
|
|
34
|
+
const prepResult = await runPrepCommands(siteName, versionType, commitMessage, localPath);
|
|
42
35
|
// Deploy to each environment
|
|
43
36
|
const environmentResults = {};
|
|
44
37
|
for (const env of environments) {
|
|
@@ -62,19 +55,19 @@ async function executeScript(siteName, versionType, commitMessage, environments,
|
|
|
62
55
|
/**
|
|
63
56
|
* Run preparation commands before deployment
|
|
64
57
|
*/
|
|
65
|
-
async function runPrepCommands(siteName, versionType, commitMessage) {
|
|
58
|
+
async function runPrepCommands(siteName, versionType, commitMessage, localPath) {
|
|
66
59
|
const results = [];
|
|
67
60
|
try {
|
|
68
61
|
// Update packages first
|
|
69
62
|
results.push('Updating packages...');
|
|
70
63
|
try {
|
|
71
|
-
const { stdout: outdatedOutput } = await execAsync('npm outdated --json', { timeout: 60000 });
|
|
64
|
+
const { stdout: outdatedOutput } = await execAsync('npm outdated --json', { timeout: 60000, cwd: localPath });
|
|
72
65
|
const outdated = JSON.parse(outdatedOutput);
|
|
73
66
|
const packagesToUpdate = Object.keys(outdated).map(pkg => `${pkg}@${outdated[pkg].latest}`);
|
|
74
67
|
if (packagesToUpdate.length > 0) {
|
|
75
68
|
for (const pkg of packagesToUpdate.slice(0, 10)) { // Limit to 10 packages to avoid timeouts
|
|
76
69
|
try {
|
|
77
|
-
await execAsync(`npm install --save ${pkg}`, { timeout: 120000 });
|
|
70
|
+
await execAsync(`npm install --save ${pkg}`, { timeout: 120000, cwd: localPath });
|
|
78
71
|
results.push(`Updated ${pkg}`);
|
|
79
72
|
}
|
|
80
73
|
catch (error) {
|
|
@@ -91,7 +84,7 @@ async function runPrepCommands(siteName, versionType, commitMessage) {
|
|
|
91
84
|
}
|
|
92
85
|
// Run linting
|
|
93
86
|
try {
|
|
94
|
-
await execAsync('npm run lint', { timeout: 120000 });
|
|
87
|
+
await execAsync('npm run lint', { timeout: 120000, cwd: localPath });
|
|
95
88
|
results.push('Linting passed');
|
|
96
89
|
}
|
|
97
90
|
catch (error) {
|
|
@@ -99,7 +92,7 @@ async function runPrepCommands(siteName, versionType, commitMessage) {
|
|
|
99
92
|
}
|
|
100
93
|
// Run audit fix
|
|
101
94
|
try {
|
|
102
|
-
await execAsync('npm audit fix --force', { timeout: 120000 });
|
|
95
|
+
await execAsync('npm audit fix --force', { timeout: 120000, cwd: localPath });
|
|
103
96
|
results.push('Security audit fixes applied');
|
|
104
97
|
}
|
|
105
98
|
catch (error) {
|
|
@@ -107,26 +100,26 @@ async function runPrepCommands(siteName, versionType, commitMessage) {
|
|
|
107
100
|
}
|
|
108
101
|
// Update version based on type
|
|
109
102
|
if (versionType === 'patch') {
|
|
110
|
-
await execAsync('npm version patch --no-git-tag-version');
|
|
103
|
+
await execAsync('npm version patch --no-git-tag-version', { cwd: localPath });
|
|
111
104
|
results.push('Updated patch version');
|
|
112
105
|
}
|
|
113
106
|
else if (versionType === 'minor') {
|
|
114
|
-
await execAsync('npm version minor --no-git-tag-version');
|
|
107
|
+
await execAsync('npm version minor --no-git-tag-version', { cwd: localPath });
|
|
115
108
|
results.push('Updated minor version');
|
|
116
109
|
}
|
|
117
110
|
else if (versionType === 'major') {
|
|
118
|
-
await execAsync('npm version major --no-git-tag-version');
|
|
111
|
+
await execAsync('npm version major --no-git-tag-version', { cwd: localPath });
|
|
119
112
|
results.push('Updated major version');
|
|
120
113
|
}
|
|
121
114
|
// Build the project
|
|
122
|
-
await execAsync('npm run build', { timeout: 300000 });
|
|
115
|
+
await execAsync('npm run build', { timeout: 300000, cwd: localPath });
|
|
123
116
|
results.push('Built project successfully');
|
|
124
117
|
// Commit changes
|
|
125
|
-
await execAsync(`git add . -v`, { timeout: 60000 });
|
|
126
|
-
await execAsync(`git commit -m "${commitMessage.replace(/"/g, '\\"')}"`, { timeout: 60000 });
|
|
118
|
+
await execAsync(`git add . -v`, { timeout: 60000, cwd: localPath });
|
|
119
|
+
await execAsync(`git commit -m "${commitMessage.replace(/"/g, '\\"')}"`, { timeout: 60000, cwd: localPath });
|
|
127
120
|
results.push(`Committed changes: ${commitMessage}`);
|
|
128
121
|
// Get the new version
|
|
129
|
-
const { stdout: version } = await execAsync('node -p "require(\'./package.json\').version"');
|
|
122
|
+
const { stdout: version } = await execAsync('node -p "require(\'./package.json\').version"', { cwd: localPath });
|
|
130
123
|
results.push(`New version: ${version.trim()}`);
|
|
131
124
|
return results.join('\n');
|
|
132
125
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SEO Analysis Constants
|
|
3
|
+
* Shared constants for SEO analysis functionality
|
|
4
|
+
*/
|
|
5
|
+
// Common URL patterns to exclude from SEO analysis
|
|
6
|
+
export const EXCLUDED_URL_PATTERNS = [
|
|
7
|
+
'/images', '/images/', '/css/', '/js/', '/assets/', '/static/',
|
|
8
|
+
'/wp-content/', '/wp-includes/', '/admin/', '/wp-admin/',
|
|
9
|
+
'/media/', '/uploads/', '/files/', '/downloads/',
|
|
10
|
+
'/api/', '/graphql', '/feed', '/rss', '/atom',
|
|
11
|
+
'/sitemap.xml', '/robots.txt', '/favicon.ico'
|
|
12
|
+
];
|
|
13
|
+
export const EXCLUDED_FILE_EXTENSIONS = /\.(jpg|jpeg|png|gif|svg|ico|css|js|woff|woff2|ttf|eot|pdf|doc|docx|xls|xlsx|zip|rar|mp3|mp4|avi|mov)$/i;
|
|
14
|
+
export const EXCLUDED_DIRECTORY_NAMES = ['images', 'css', 'js', 'assets', 'static', 'media'];
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CloudWatch Health Check Integration Services
|
|
3
|
+
* Server-side utilities for Route53 health check data retrieval via CloudWatch
|
|
4
|
+
*/
|
|
5
|
+
"use server";
|
|
6
|
+
import { CloudWatchClient, GetMetricDataCommand } from '@aws-sdk/client-cloudwatch';
|
|
7
|
+
import { RouteCache } from './site-health-cache';
|
|
8
|
+
// Cache for health check data (15 minutes)
|
|
9
|
+
const healthCheckCache = new RouteCache(15 * 60 * 1000);
|
|
10
|
+
/**
|
|
11
|
+
* Get health check data for a site using CloudWatch metrics
|
|
12
|
+
*/
|
|
13
|
+
export async function getCloudwatchHealthCheckData(config, siteName, startDate, endDate) {
|
|
14
|
+
try {
|
|
15
|
+
// Check cache first
|
|
16
|
+
const cacheKey = `cloudwatch-${siteName}-${config.healthCheckId}-${startDate || 'default'}-${endDate || 'default'}`;
|
|
17
|
+
const cached = healthCheckCache.get(cacheKey);
|
|
18
|
+
if (cached) {
|
|
19
|
+
return { success: true, data: cached };
|
|
20
|
+
}
|
|
21
|
+
// Use CloudWatch to get historical health check data
|
|
22
|
+
const cloudWatchClient = new CloudWatchClient({
|
|
23
|
+
region: config.region || 'us-east-1'
|
|
24
|
+
});
|
|
25
|
+
// Set up date range
|
|
26
|
+
const endTime = endDate ? new Date(endDate) : new Date();
|
|
27
|
+
const startTime = startDate ? new Date(startDate) : new Date(endTime.getTime() - (30 * 24 * 60 * 60 * 1000)); // 30 days ago
|
|
28
|
+
// Add 1 day to end time to include the full end date
|
|
29
|
+
const endTimePlusOne = new Date(endTime);
|
|
30
|
+
endTimePlusOne.setDate(endTimePlusOne.getDate() + 1);
|
|
31
|
+
console.log(`CloudWatch: Fetching data for health check ${config.healthCheckId} from ${startTime.toISOString()} to ${endTimePlusOne.toISOString()}`);
|
|
32
|
+
const metricDataQuery = {
|
|
33
|
+
MetricDataQueries: [
|
|
34
|
+
{
|
|
35
|
+
Id: 'healthCheckStatus',
|
|
36
|
+
MetricStat: {
|
|
37
|
+
Metric: {
|
|
38
|
+
Namespace: 'AWS/Route53',
|
|
39
|
+
MetricName: 'HealthCheckStatus',
|
|
40
|
+
Dimensions: [
|
|
41
|
+
{
|
|
42
|
+
Name: 'HealthCheckId',
|
|
43
|
+
Value: config.healthCheckId
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
},
|
|
47
|
+
Period: 3600, // 1 hour intervals
|
|
48
|
+
Stat: 'Average'
|
|
49
|
+
},
|
|
50
|
+
ReturnData: true
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
StartTime: startTime,
|
|
54
|
+
EndTime: endTimePlusOne
|
|
55
|
+
};
|
|
56
|
+
const command = new GetMetricDataCommand(metricDataQuery);
|
|
57
|
+
const response = await cloudWatchClient.send(command);
|
|
58
|
+
console.log(`CloudWatch: Received ${response.MetricDataResults?.[0]?.Timestamps?.length || 0} data points`);
|
|
59
|
+
if (!response.MetricDataResults || response.MetricDataResults.length === 0) {
|
|
60
|
+
console.log(`CloudWatch: No metric data found for health check ${config.healthCheckId}`);
|
|
61
|
+
return {
|
|
62
|
+
success: false,
|
|
63
|
+
error: 'No health check metric data found'
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
const metricResult = response.MetricDataResults[0];
|
|
67
|
+
if (!metricResult.Timestamps || !metricResult.Values) {
|
|
68
|
+
console.log(`CloudWatch: No timestamps or values in metric data`);
|
|
69
|
+
return {
|
|
70
|
+
success: false,
|
|
71
|
+
error: 'No health check metric data available'
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
// Group data by date
|
|
75
|
+
const dateGroups = {};
|
|
76
|
+
metricResult.Timestamps.forEach((timestamp, index) => {
|
|
77
|
+
const date = timestamp.toISOString().split('T')[0]; // YYYY-MM-DD
|
|
78
|
+
const value = metricResult.Values[index];
|
|
79
|
+
if (!dateGroups[date]) {
|
|
80
|
+
dateGroups[date] = { success: 0, failure: 0 };
|
|
81
|
+
}
|
|
82
|
+
// CloudWatch returns 1 for healthy, 0 for unhealthy
|
|
83
|
+
if (value >= 0.5) { // Consider >= 0.5 as success
|
|
84
|
+
dateGroups[date].success++;
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
dateGroups[date].failure++;
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
// Convert to data points
|
|
91
|
+
const data = Object.entries(dateGroups)
|
|
92
|
+
.map(([date, counts]) => {
|
|
93
|
+
const total = counts.success + counts.failure;
|
|
94
|
+
const successRate = total > 0 ? (counts.success / total) * 100 : 0;
|
|
95
|
+
return {
|
|
96
|
+
date,
|
|
97
|
+
successCount: counts.success,
|
|
98
|
+
failureCount: counts.failure,
|
|
99
|
+
totalChecks: total,
|
|
100
|
+
successRate: Math.round(successRate * 100) / 100 // Round to 2 decimal places
|
|
101
|
+
};
|
|
102
|
+
})
|
|
103
|
+
.sort((a, b) => a.date.localeCompare(b.date));
|
|
104
|
+
console.log(`CloudWatch: Processed ${data.length} date groups with data`);
|
|
105
|
+
// Fill in the date range with data points for each day
|
|
106
|
+
let filledData = [];
|
|
107
|
+
if (startDate && endDate) {
|
|
108
|
+
const start = new Date(startDate);
|
|
109
|
+
const end = new Date(endDate);
|
|
110
|
+
const dataMap = new Map(data.map(d => [d.date, d]));
|
|
111
|
+
for (let date = new Date(start); date <= end; date.setDate(date.getDate() + 1)) {
|
|
112
|
+
const dateStr = date.toISOString().split('T')[0];
|
|
113
|
+
const existingData = dataMap.get(dateStr);
|
|
114
|
+
if (existingData) {
|
|
115
|
+
filledData.push(existingData);
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
filledData.push({
|
|
119
|
+
date: dateStr,
|
|
120
|
+
successCount: 0,
|
|
121
|
+
failureCount: 0,
|
|
122
|
+
totalChecks: 0,
|
|
123
|
+
successRate: 0
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
filledData = data;
|
|
130
|
+
}
|
|
131
|
+
// Cache the result
|
|
132
|
+
healthCheckCache.set(cacheKey, filledData);
|
|
133
|
+
return { success: true, data: filledData };
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
console.error('CloudWatch error:', error);
|
|
137
|
+
return {
|
|
138
|
+
success: false,
|
|
139
|
+
error: error instanceof Error ? error.message : 'Failed to fetch health check data from CloudWatch'
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { ComposedChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts';
|
|
4
|
+
import { SiteHealthTemplate } from './site-health-template';
|
|
5
|
+
export function SiteHealthCloudwatch({ siteName, startDate, endDate }) {
|
|
6
|
+
const fetchCloudwatchData = async (site) => {
|
|
7
|
+
const params = new URLSearchParams({ siteName: site });
|
|
8
|
+
if (startDate)
|
|
9
|
+
params.append('startDate', startDate);
|
|
10
|
+
if (endDate)
|
|
11
|
+
params.append('endDate', endDate);
|
|
12
|
+
const response = await fetch(`/api/site-health/cloudwatch?${params.toString()}`);
|
|
13
|
+
if (!response.ok) {
|
|
14
|
+
throw new Error(`Failed to fetch CloudWatch data: ${response.status}`);
|
|
15
|
+
}
|
|
16
|
+
const result = await response.json();
|
|
17
|
+
if (!result.success) {
|
|
18
|
+
if (result.error?.includes('Health Check ID not configured')) {
|
|
19
|
+
throw new Error('Route53 Health Check ID not configured for this site');
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
throw new Error(result.error || 'Failed to load CloudWatch health check data');
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return result.data;
|
|
26
|
+
};
|
|
27
|
+
return (_jsx(SiteHealthTemplate, { siteName: siteName, title: "CloudWatch Uptime", columnSpan: 2, fetchData: fetchCloudwatchData, children: (data) => {
|
|
28
|
+
if (!data || data.length === 0) {
|
|
29
|
+
return (_jsx("div", { className: "flex items-center justify-center h-64", children: _jsx("div", { className: "text-gray-500", children: "No uptime data available. Route53 health checks may not be configured to send metrics to CloudWatch." }) }));
|
|
30
|
+
}
|
|
31
|
+
// Check if all data points have zero checks (no actual data)
|
|
32
|
+
const hasActualData = data.some(point => point.totalChecks > 0);
|
|
33
|
+
if (!hasActualData) {
|
|
34
|
+
return (_jsx("div", { className: "flex items-center justify-center h-64", children: _jsxs("div", { className: "text-gray-500", children: ["Health check exists but has no metric data in CloudWatch for the selected period.", _jsx("br", {}), "Route53 health checks must be configured to send metrics to CloudWatch for historical data."] }) }));
|
|
35
|
+
}
|
|
36
|
+
return (_jsx("div", { children: _jsx("div", { style: { width: '100%', height: '400px', border: '1px solid #ddd' }, children: _jsx(ResponsiveContainer, { width: "100%", height: "100%", children: _jsxs(ComposedChart, { data: data, margin: { top: 40, right: 30, left: 20, bottom: 5 }, children: [_jsx("text", { x: "50%", y: 20, textAnchor: "middle", fontSize: "16", fontWeight: "bold", fill: "#374151", children: "CloudWatch Health Check Availability Over Time" }), _jsx(CartesianGrid, { strokeDasharray: "3 3" }), _jsx(XAxis, { dataKey: "date", tick: { fontSize: 12 }, angle: -45, textAnchor: "end", height: 60 }), _jsx(YAxis, { tick: { fontSize: 12 }, label: { value: 'Check Count', angle: -90, position: 'insideLeft' } }), _jsx(Tooltip, { formatter: (value, name) => [
|
|
37
|
+
value?.toLocaleString() || '0',
|
|
38
|
+
name || 'Unknown'
|
|
39
|
+
], labelFormatter: (label) => `Date: ${label}` }), _jsx(Legend, { wrapperStyle: {
|
|
40
|
+
fontSize: '12px',
|
|
41
|
+
paddingTop: '10px'
|
|
42
|
+
} }), _jsx(Bar, { dataKey: "successCount", stackId: "checks", fill: "#10b981", name: "Successful Checks", radius: [2, 2, 0, 0] }), _jsx(Bar, { dataKey: "failureCount", stackId: "checks", fill: "#ef4444", name: "Failed Checks", radius: [2, 2, 0, 0] })] }, `cloudwatch-chart-${data.length}`) }) }) }));
|
|
43
|
+
} }));
|
|
44
|
+
}
|
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
import fs from 'fs';
|
|
8
8
|
import path from 'path';
|
|
9
9
|
import { fileURLToPath } from 'url';
|
|
10
|
+
import puppeteer from 'puppeteer';
|
|
11
|
+
import { EXCLUDED_URL_PATTERNS, EXCLUDED_FILE_EXTENSIONS, EXCLUDED_DIRECTORY_NAMES } from './seo-constants';
|
|
10
12
|
const __filename = fileURLToPath(import.meta.url);
|
|
11
13
|
const __dirname = path.dirname(__filename);
|
|
12
14
|
const seoMetricsConfig = JSON.parse(fs.readFileSync(path.join(__dirname, 'seo-metrics.config.json'), 'utf8'));
|
|
@@ -258,8 +260,14 @@ async function crawlSite(baseUrl, maxPages = 10) {
|
|
|
258
260
|
try {
|
|
259
261
|
const href = match[1];
|
|
260
262
|
const absoluteUrl = new URL(href, currentUrl).toString();
|
|
261
|
-
// Only include same domain links
|
|
262
|
-
|
|
263
|
+
// Only include same domain links that look like pages
|
|
264
|
+
const urlObj = new URL(absoluteUrl);
|
|
265
|
+
const pathname = urlObj.pathname.toLowerCase();
|
|
266
|
+
// Exclude common non-page directories and files
|
|
267
|
+
const isExcluded = EXCLUDED_URL_PATTERNS.some(pattern => pathname.includes(pattern)) ||
|
|
268
|
+
pathname.match(EXCLUDED_FILE_EXTENSIONS) ||
|
|
269
|
+
EXCLUDED_DIRECTORY_NAMES.some(dir => pathname.endsWith(`/${dir}`));
|
|
270
|
+
if (urlObj.hostname === baseDomain && !visited.has(absoluteUrl) && !toVisit.includes(absoluteUrl) && !isExcluded) {
|
|
263
271
|
toVisit.push(absoluteUrl);
|
|
264
272
|
}
|
|
265
273
|
}
|
|
@@ -279,28 +287,94 @@ async function crawlSite(baseUrl, maxPages = 10) {
|
|
|
279
287
|
return discovered.slice(0, maxPages);
|
|
280
288
|
}
|
|
281
289
|
/**
|
|
282
|
-
* Analyze a single page for on-page SEO elements using
|
|
290
|
+
* Analyze a single page for on-page SEO elements using Puppeteer for full rendering
|
|
283
291
|
*/
|
|
284
292
|
async function analyzeSinglePage(url) {
|
|
293
|
+
let browser;
|
|
285
294
|
try {
|
|
286
|
-
|
|
287
|
-
|
|
295
|
+
// Reuse browser instance if available, otherwise create new one
|
|
296
|
+
browser = globalThis.__seoBrowser;
|
|
297
|
+
if (!browser || browser.isConnected() === false) {
|
|
298
|
+
browser = await puppeteer.launch({
|
|
299
|
+
headless: true,
|
|
300
|
+
args: [
|
|
301
|
+
'--no-sandbox',
|
|
302
|
+
'--disable-setuid-sandbox',
|
|
303
|
+
'--disable-dev-shm-usage',
|
|
304
|
+
'--disable-accelerated-2d-canvas',
|
|
305
|
+
'--no-first-run',
|
|
306
|
+
'--no-zygote',
|
|
307
|
+
'--disable-gpu',
|
|
308
|
+
'--disable-web-security',
|
|
309
|
+
'--disable-features=VizDisplayCompositor',
|
|
310
|
+
'--disable-extensions',
|
|
311
|
+
'--disable-plugins',
|
|
312
|
+
'--disable-default-apps',
|
|
313
|
+
'--disable-background-timer-throttling',
|
|
314
|
+
'--disable-backgrounding-occluded-windows',
|
|
315
|
+
'--disable-renderer-backgrounding'
|
|
316
|
+
]
|
|
317
|
+
});
|
|
318
|
+
globalThis.__seoBrowser = browser;
|
|
319
|
+
}
|
|
320
|
+
const page = await browser.newPage();
|
|
321
|
+
// Block unnecessary resources for faster loading while preserving SEO-relevant content
|
|
322
|
+
await page.setRequestInterception(true);
|
|
323
|
+
page.on('request', (request) => {
|
|
324
|
+
const resourceType = request.resourceType();
|
|
325
|
+
const url = request.url();
|
|
326
|
+
// Block heavy resources that slow down loading but aren't needed for HTML structure
|
|
327
|
+
if (resourceType === 'image' ||
|
|
328
|
+
resourceType === 'media' ||
|
|
329
|
+
url.includes('.jpg') ||
|
|
330
|
+
url.includes('.jpeg') ||
|
|
331
|
+
url.includes('.png') ||
|
|
332
|
+
url.includes('.gif') ||
|
|
333
|
+
url.includes('.webp') ||
|
|
334
|
+
url.includes('google-analytics.com') ||
|
|
335
|
+
url.includes('googletagmanager.com') ||
|
|
336
|
+
url.includes('facebook.com/tr') ||
|
|
337
|
+
url.includes('doubleclick.net')) {
|
|
338
|
+
request.abort();
|
|
339
|
+
}
|
|
340
|
+
else {
|
|
341
|
+
request.continue();
|
|
342
|
+
}
|
|
288
343
|
});
|
|
289
|
-
|
|
290
|
-
|
|
344
|
+
// Set smaller viewport for faster rendering
|
|
345
|
+
await page.setViewport({ width: 800, height: 600 });
|
|
346
|
+
// Set user agent to avoid bot detection
|
|
347
|
+
await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36');
|
|
348
|
+
// Navigate to the page with faster waiting strategy
|
|
349
|
+
const response = await page.goto(url, {
|
|
350
|
+
waitUntil: 'domcontentloaded', // Wait for DOM instead of all network requests
|
|
351
|
+
timeout: 15000 // Reduced timeout
|
|
352
|
+
});
|
|
353
|
+
// Wait for H1 elements to be rendered (if any) with a short timeout
|
|
354
|
+
try {
|
|
355
|
+
await page.waitForSelector('h1', { timeout: 2000 });
|
|
356
|
+
}
|
|
357
|
+
catch {
|
|
358
|
+
// H1 not found within timeout, continue anyway
|
|
359
|
+
}
|
|
360
|
+
// Get title and heading counts directly from DOM for speed
|
|
361
|
+
const pageData = await page.evaluate(() => {
|
|
291
362
|
return {
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
363
|
+
title: document.title,
|
|
364
|
+
h1Count: document.querySelectorAll('h1').length,
|
|
365
|
+
h2Count: document.querySelectorAll('h2').length,
|
|
366
|
+
h1Elements: Array.from(document.querySelectorAll('h1')).map(h1 => ({
|
|
367
|
+
text: h1.textContent?.trim() || ''
|
|
368
|
+
})),
|
|
369
|
+
h2Elements: Array.from(document.querySelectorAll('h2')).map(h2 => ({
|
|
370
|
+
text: h2.textContent?.trim() || ''
|
|
371
|
+
}))
|
|
297
372
|
};
|
|
298
|
-
}
|
|
299
|
-
|
|
373
|
+
});
|
|
374
|
+
// Get the rendered HTML for other pattern-based checks
|
|
375
|
+
const html = await page.content();
|
|
376
|
+
await page.close();
|
|
300
377
|
const audits = [];
|
|
301
|
-
// Extract page title for title tag analysis
|
|
302
|
-
const titleMatch = html.match(/<title[^>]*>([^<]*)<\/title>/i);
|
|
303
|
-
const pageTitle = titleMatch ? titleMatch[1].trim() : undefined;
|
|
304
378
|
// Process on-page metrics from configuration
|
|
305
379
|
const config = seoMetricsConfig;
|
|
306
380
|
const onPageCategory = config.categories['on-page'];
|
|
@@ -313,7 +387,7 @@ async function analyzeSinglePage(url) {
|
|
|
313
387
|
const collector = dataCollectors[metric.dataCollector];
|
|
314
388
|
const scorer = scorers[metric.scorer];
|
|
315
389
|
if (collector && scorer) {
|
|
316
|
-
const rawData = collector(html,
|
|
390
|
+
const rawData = collector(html, pageData.title);
|
|
317
391
|
const result = scorer(rawData);
|
|
318
392
|
score = result.score;
|
|
319
393
|
displayValue = result.displayValue;
|
|
@@ -327,6 +401,17 @@ async function analyzeSinglePage(url) {
|
|
|
327
401
|
displayValue = result.displayValue;
|
|
328
402
|
details = result.details;
|
|
329
403
|
}
|
|
404
|
+
// Override H1 and H2 results with direct DOM counts for accuracy and speed
|
|
405
|
+
if (metric.id === 'h1-tags') {
|
|
406
|
+
score = pageData.h1Count === (metric.expectedCount || 1) ? 1 : 0;
|
|
407
|
+
displayValue = `${pageData.h1Count} H1 tag(s) found`;
|
|
408
|
+
details = { items: pageData.h1Elements.map((h1) => ({ tag: 'h1', text: h1.text })) };
|
|
409
|
+
}
|
|
410
|
+
else if (metric.id === 'h2-tags') {
|
|
411
|
+
score = pageData.h2Count > 0 ? 1 : 0;
|
|
412
|
+
displayValue = `${pageData.h2Count} H2 tag(s) found`;
|
|
413
|
+
details = { items: pageData.h2Elements.map((h2) => ({ tag: 'h2', text: h2.text })) };
|
|
414
|
+
}
|
|
330
415
|
audits.push({
|
|
331
416
|
id: metric.id,
|
|
332
417
|
title: metric.title,
|
|
@@ -339,8 +424,8 @@ async function analyzeSinglePage(url) {
|
|
|
339
424
|
}
|
|
340
425
|
return {
|
|
341
426
|
url,
|
|
342
|
-
title:
|
|
343
|
-
statusCode: response.status,
|
|
427
|
+
title: pageData.title,
|
|
428
|
+
statusCode: response.status(),
|
|
344
429
|
audits,
|
|
345
430
|
crawledAt: new Date().toISOString()
|
|
346
431
|
};
|
|
@@ -356,6 +441,11 @@ async function analyzeSinglePage(url) {
|
|
|
356
441
|
crawledAt: new Date().toISOString()
|
|
357
442
|
};
|
|
358
443
|
}
|
|
444
|
+
finally {
|
|
445
|
+
if (browser) {
|
|
446
|
+
await browser.close();
|
|
447
|
+
}
|
|
448
|
+
}
|
|
359
449
|
}
|
|
360
450
|
async function performSiteWideAudits(baseUrl) {
|
|
361
451
|
const audits = [];
|
|
@@ -470,14 +560,15 @@ async function getUrlsFromSitemap(baseUrl) {
|
|
|
470
560
|
// Only include URLs from the same domain and that look like valid page URLs
|
|
471
561
|
try {
|
|
472
562
|
const urlObj = new URL(url);
|
|
473
|
-
if (urlObj.hostname === baseUrlObj.hostname
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
!
|
|
480
|
-
|
|
563
|
+
if (urlObj.hostname === baseUrlObj.hostname) {
|
|
564
|
+
const pathname = urlObj.pathname.toLowerCase();
|
|
565
|
+
// Exclude common non-page directories and files
|
|
566
|
+
const isExcluded = EXCLUDED_URL_PATTERNS.some(pattern => pathname.includes(pattern)) ||
|
|
567
|
+
pathname.match(EXCLUDED_FILE_EXTENSIONS) ||
|
|
568
|
+
EXCLUDED_DIRECTORY_NAMES.some(dir => pathname.endsWith(`/${dir}`));
|
|
569
|
+
if (!isExcluded) {
|
|
570
|
+
urls.push(url);
|
|
571
|
+
}
|
|
481
572
|
}
|
|
482
573
|
}
|
|
483
574
|
catch {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
2
3
|
import React, { useState, useEffect } from 'react';
|
|
3
4
|
export function LinkedIn() {
|
|
4
5
|
const [data, setData] = useState(null);
|
|
@@ -33,25 +34,16 @@ export function LinkedIn() {
|
|
|
33
34
|
});
|
|
34
35
|
const fullRecommendsURL = proxyURL + LinkedInApi.recommendUrl + "?" + recommendParams.toString();
|
|
35
36
|
async function fetchOAuth() {
|
|
36
|
-
console.log("Fetching LinkedIn oAuth Token");
|
|
37
37
|
try {
|
|
38
|
-
console.log("OAuth URL : ", fullOAuthURL);
|
|
39
|
-
// const oAuthPromise = await fetch(fullOAuthURL, { method: 'GET' });
|
|
40
|
-
// const oAuthPromise = await fetch(LinkedInApi.oAuthUrl + "?" + oAuthParams.toString(), { method: 'GET' });
|
|
41
38
|
window.location.href = fullOAuthURL;
|
|
42
|
-
// console.log(await oAuthPromise);
|
|
43
|
-
// const response = await oAuthPromise.response;
|
|
44
|
-
// console.log(await response);
|
|
45
39
|
}
|
|
46
40
|
catch (err) {
|
|
47
41
|
console.log("Error : ", err);
|
|
48
42
|
}
|
|
49
43
|
}
|
|
50
44
|
async function fetchAccessToken() {
|
|
51
|
-
console.log("Fetching LinkedIn Access Token");
|
|
52
45
|
try {
|
|
53
46
|
const fullTokenURL = proxyURL + LinkedInApi.tokenUrl;
|
|
54
|
-
console.log("Access Token URL : ", fullTokenURL);
|
|
55
47
|
const tokenPromise = await fetch(fullTokenURL, {
|
|
56
48
|
method: 'POST',
|
|
57
49
|
headers: {
|
|
@@ -64,24 +56,15 @@ export function LinkedIn() {
|
|
|
64
56
|
'client_secret': LinkedInApi.clientSecret
|
|
65
57
|
}
|
|
66
58
|
});
|
|
67
|
-
console.log(tokenPromise);
|
|
68
|
-
const response = await tokenPromise.response;
|
|
69
|
-
console.log(await response);
|
|
70
|
-
console.log("Access Token : ", await response.data);
|
|
71
59
|
}
|
|
72
60
|
catch (err) {
|
|
73
61
|
console.log("Error : ", err);
|
|
74
62
|
}
|
|
75
63
|
}
|
|
76
64
|
async function fetchRecommendations() {
|
|
77
|
-
console.log("Fetching LinkedIn Recommendations");
|
|
78
65
|
try {
|
|
79
|
-
console.log(fullRecommendsURL);
|
|
80
66
|
const recommendPromise = await fetch(fullRecommendsURL, { method: 'GET' });
|
|
81
|
-
console.log(await recommendPromise);
|
|
82
67
|
const response = await recommendPromise.response;
|
|
83
|
-
console.log(await response);
|
|
84
|
-
console.log(await response.body);
|
|
85
68
|
setData(await response.body);
|
|
86
69
|
}
|
|
87
70
|
catch (err) {
|
|
@@ -90,7 +73,6 @@ export function LinkedIn() {
|
|
|
90
73
|
}
|
|
91
74
|
useEffect(() => {
|
|
92
75
|
if (codeParam) {
|
|
93
|
-
console.log("Access Token Is Present");
|
|
94
76
|
fetchAccessToken()
|
|
95
77
|
.then(fetchRecommendations());
|
|
96
78
|
}
|
|
@@ -136,7 +136,8 @@ export function ShoppingCart(props) {
|
|
|
136
136
|
'orderData': JSON.stringify(orderData, null, 2),
|
|
137
137
|
};
|
|
138
138
|
const sendMailResponse = emailJSON(json);
|
|
139
|
-
|
|
139
|
+
if (debug)
|
|
140
|
+
console.log("SendMail Response:", sendMailResponse);
|
|
140
141
|
// ========== THANK YOU ==========
|
|
141
142
|
const pmt = orderData.purchase_units[0].payments.captures[0];
|
|
142
143
|
return (_jsxs("div", { className: "pixCart", children: [_jsx(CalloutHeader, { title: "Shopping Cart : " }), _jsx("br", {}), _jsx("div", { id: "paypal-button-container", className: "paypal-button-container" }), _jsxs("div", { children: [_jsx("h3", { children: "Thank you for your payment!" }), "Payment ID : ", pmt.id, " ", _jsx("br", {}), "Status : ", pmt.status, " ", _jsx("br", {}), "Amount : $", pmt.amount.value + " " + pmt.amount.currency_code, " ", _jsx("br", {}), "Created : ", pmt.create_time, " ", _jsx("br", {})] })] }));
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const debug = false;
|
|
1
2
|
export function html2dom(str) {
|
|
2
3
|
if (window.DOMParser) {
|
|
3
4
|
const parser = new DOMParser();
|
|
@@ -111,12 +112,14 @@ export function logAllChange() {
|
|
|
111
112
|
(targetElement.tagName === 'INPUT' ||
|
|
112
113
|
targetElement.tagName === 'SELECT' ||
|
|
113
114
|
targetElement.tagName === 'TEXTAREA')) {
|
|
114
|
-
|
|
115
|
+
if (debug)
|
|
116
|
+
console.log('Change event triggered:', event);
|
|
115
117
|
// For text inputs, the change event only fires when the element loses focus
|
|
116
118
|
// For checkboxes/radio buttons, event.target.checked provides the value
|
|
117
119
|
const inputElement = targetElement;
|
|
118
120
|
const changeValue = inputElement.type === 'checkbox' || inputElement.type === 'radio' ? inputElement.checked : inputElement.value;
|
|
119
|
-
|
|
121
|
+
if (debug)
|
|
122
|
+
console.log('Changed value:', changeValue);
|
|
120
123
|
}
|
|
121
124
|
});
|
|
122
125
|
}
|
package/dist/index.js
CHANGED
|
@@ -88,6 +88,8 @@ export * from './components/admin/site-health/site-health-github';
|
|
|
88
88
|
export * from './components/admin/site-health/site-health-google-analytics';
|
|
89
89
|
export * from './components/admin/site-health/site-health-google-search-console';
|
|
90
90
|
export * from './components/admin/site-health/site-health-on-site-seo';
|
|
91
|
+
export * from './components/admin/site-health/site-health-cloudwatch';
|
|
92
|
+
export * from './components/admin/site-health/seo-constants';
|
|
91
93
|
export * from './components/admin/site-health/site-health-overview';
|
|
92
94
|
export * from './components/admin/site-health/site-health-performance';
|
|
93
95
|
export * from './components/admin/site-health/site-health-security';
|
package/dist/index.server.js
CHANGED
|
@@ -14,6 +14,8 @@ export * from './components/admin/site-health/site-health-google-analytics.integ
|
|
|
14
14
|
export * from './components/admin/site-health/site-health-google-search-console.integration';
|
|
15
15
|
export * from './components/admin/site-health/site-health-indicators';
|
|
16
16
|
export * from './components/admin/site-health/site-health-on-site-seo.integration';
|
|
17
|
+
export * from './components/admin/site-health/site-health-cloudwatch.integration';
|
|
18
|
+
export * from './components/admin/site-health/seo-constants';
|
|
17
19
|
export * from './components/admin/site-health/site-health-security.integration';
|
|
18
20
|
export * from './components/admin/site-health/site-health-performance';
|
|
19
21
|
export * from './components/admin/site-health/site-health-types';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SEO Analysis Constants
|
|
3
|
+
* Shared constants for SEO analysis functionality
|
|
4
|
+
*/
|
|
5
|
+
export declare const EXCLUDED_URL_PATTERNS: string[];
|
|
6
|
+
export declare const EXCLUDED_FILE_EXTENSIONS: RegExp;
|
|
7
|
+
export declare const EXCLUDED_DIRECTORY_NAMES: string[];
|
|
8
|
+
//# sourceMappingURL=seo-constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seo-constants.d.ts","sourceRoot":"","sources":["../../../../../src/components/admin/site-health/seo-constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,eAAO,MAAM,qBAAqB,UAMjC,CAAC;AAEF,eAAO,MAAM,wBAAwB,QAA2G,CAAC;AAEjJ,eAAO,MAAM,wBAAwB,UAAuD,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
interface SiteHealthCloudwatchProps {
|
|
2
|
+
siteName: string;
|
|
3
|
+
startDate?: string;
|
|
4
|
+
endDate?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function SiteHealthCloudwatch({ siteName, startDate, endDate }: SiteHealthCloudwatchProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=site-health-cloudwatch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"site-health-cloudwatch.d.ts","sourceRoot":"","sources":["../../../../../src/components/admin/site-health/site-health-cloudwatch.tsx"],"names":[],"mappings":"AAcA,UAAU,yBAAyB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,oBAAoB,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,yBAAyB,2CAiH/F"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CloudWatch Health Check Integration Services
|
|
3
|
+
* Server-side utilities for Route53 health check data retrieval via CloudWatch
|
|
4
|
+
*/
|
|
5
|
+
export interface CloudwatchHealthCheckConfig {
|
|
6
|
+
healthCheckId: string;
|
|
7
|
+
region?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface HealthCheckDataPoint {
|
|
10
|
+
date: string;
|
|
11
|
+
successCount: number;
|
|
12
|
+
failureCount: number;
|
|
13
|
+
totalChecks: number;
|
|
14
|
+
successRate: number;
|
|
15
|
+
}
|
|
16
|
+
export interface CloudwatchHealthCheckResponse {
|
|
17
|
+
success: boolean;
|
|
18
|
+
data?: HealthCheckDataPoint[];
|
|
19
|
+
error?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Get health check data for a site using CloudWatch metrics
|
|
23
|
+
*/
|
|
24
|
+
export declare function getCloudwatchHealthCheckData(config: CloudwatchHealthCheckConfig, siteName: string, startDate?: string, endDate?: string): Promise<CloudwatchHealthCheckResponse>;
|
|
25
|
+
//# sourceMappingURL=site-health-cloudwatch.integration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"site-health-cloudwatch.integration.d.ts","sourceRoot":"","sources":["../../../../../src/components/admin/site-health/site-health-cloudwatch.integration.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,MAAM,WAAW,2BAA2B;IAC1C,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,6BAA6B;IAC7C,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,oBAAoB,EAAE,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAKD;;GAEG;AACH,wBAAsB,4BAA4B,CACjD,MAAM,EAAE,2BAA2B,EACnC,QAAQ,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,6BAA6B,CAAC,CAiJxC"}
|
package/dist/types/components/admin/site-health/site-health-on-site-seo.integration.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"site-health-on-site-seo.integration.d.ts","sourceRoot":"","sources":["../../../../../src/components/admin/site-health/site-health-on-site-seo.integration.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"site-health-on-site-seo.integration.d.ts","sourceRoot":"","sources":["../../../../../src/components/admin/site-health/site-health-on-site-seo.integration.ts"],"names":[],"mappings":"AA+RA,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,gBAAgB,EAAE,QAAQ,GAAG,eAAe,CAAC;IAC7C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,SAAS,GAAG,SAAS,CAAC;IAChC,OAAO,CAAC,EAAE;QACR,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;KACxC,CAAC;CACH;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,YAAY,EAAE,cAAc,EAAE,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAuYD;;GAEG;AACH,wBAAsB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAwFtF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pixelated.linkedin1.d.ts","sourceRoot":"","sources":["../../../../src/components/cms/pixelated.linkedin1.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pixelated.linkedin1.d.ts","sourceRoot":"","sources":["../../../../src/components/cms/pixelated.linkedin1.js"],"names":[],"mappings":"AAGA,oEAiGC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"functions.d.ts","sourceRoot":"","sources":["../../../../src/components/utilities/functions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"functions.d.ts","sourceRoot":"","sources":["../../../../src/components/utilities/functions.ts"],"names":[],"mappings":"AAGA,wBAAgB,QAAQ,CAAE,GAAG,EAAE,MAAM,oBAUpC;AAGD,wBAAgB,SAAS,CAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG;;EAmBxC;AAED,wBAAgB,wBAAwB,CAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,QAIhF;AAED,wBAAgB,aAAa,CAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,UAOtD;AAED,wBAAgB,WAAW,WAc1B;AAED,wBAAgB,YAAY,WAK3B;AAED,wBAAgB,UAAU,CAAE,GAAG,EAAE,MAAM,UAEtC;AAQD,wBAAgB,YAAY,CAAE,YAAY,EAAE,MAAM,UAgCjD;AAID;;;;OAII;AACJ,wBAAgB,YAAY,SAoB3B"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -87,6 +87,8 @@ export * from "./components/admin/site-health/site-health-github";
|
|
|
87
87
|
export * from "./components/admin/site-health/site-health-google-analytics";
|
|
88
88
|
export * from "./components/admin/site-health/site-health-google-search-console";
|
|
89
89
|
export * from "./components/admin/site-health/site-health-on-site-seo";
|
|
90
|
+
export * from "./components/admin/site-health/site-health-cloudwatch";
|
|
91
|
+
export * from "./components/admin/site-health/seo-constants";
|
|
90
92
|
export * from "./components/admin/site-health/site-health-overview";
|
|
91
93
|
export * from "./components/admin/site-health/site-health-performance";
|
|
92
94
|
export * from "./components/admin/site-health/site-health-security";
|
|
@@ -10,6 +10,8 @@ export * from "./components/admin/site-health/site-health-google-analytics.integ
|
|
|
10
10
|
export * from "./components/admin/site-health/site-health-google-search-console.integration";
|
|
11
11
|
export * from "./components/admin/site-health/site-health-indicators";
|
|
12
12
|
export * from "./components/admin/site-health/site-health-on-site-seo.integration";
|
|
13
|
+
export * from "./components/admin/site-health/site-health-cloudwatch.integration";
|
|
14
|
+
export * from "./components/admin/site-health/seo-constants";
|
|
13
15
|
export * from "./components/admin/site-health/site-health-security.integration";
|
|
14
16
|
export * from "./components/admin/site-health/site-health-performance";
|
|
15
17
|
export * from "./components/admin/site-health/site-health-types";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tiles.stories.d.ts","sourceRoot":"","sources":["../../../../src/stories/carousel/tiles.stories.js"],"names":[],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"tiles.stories.d.ts","sourceRoot":"","sources":["../../../../src/stories/carousel/tiles.stories.js"],"names":[],"mappings":";;;;;;AAkFO,sEAAwC;sBAjFzB,6BAA6B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pixelated-tech/components",
|
|
3
|
-
"version": "3.4.
|
|
3
|
+
"version": "3.4.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Pixelated Technologies",
|
|
@@ -79,6 +79,7 @@
|
|
|
79
79
|
"build-webpack-rsync": "rsync -a --include='*' --include='*/' src/css dist/css"
|
|
80
80
|
},
|
|
81
81
|
"dependencies": {
|
|
82
|
+
"@aws-sdk/client-cloudwatch": "^3.958.0",
|
|
82
83
|
"@aws-sdk/client-route-53": "^3.958.0",
|
|
83
84
|
"date-fns": "^4.1.0",
|
|
84
85
|
"globals": "^17.0.0",
|