@duffcloudservices/cli 0.1.1 → 0.1.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/README.md +158 -158
- package/dist/index.js +226 -187
- package/dist/index.js.map +1 -1
- package/package.json +4 -1
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { Command } from "commander";
|
|
|
5
5
|
import chalk8 from "chalk";
|
|
6
6
|
|
|
7
7
|
// package.json
|
|
8
|
-
var version = "0.1.
|
|
8
|
+
var version = "0.1.2";
|
|
9
9
|
|
|
10
10
|
// src/commands/auth.ts
|
|
11
11
|
import chalk2 from "chalk";
|
|
@@ -441,181 +441,198 @@ import chalk4 from "chalk";
|
|
|
441
441
|
import ora2 from "ora";
|
|
442
442
|
|
|
443
443
|
// src/templates/site-deploy.yml
|
|
444
|
-
var site_deploy_default = `# Site Deployment Workflow
|
|
445
|
-
# Generated by @duffcloudservices/cli
|
|
446
|
-
# This workflow deploys the site to Azure Static Web Apps using OIDC authentication
|
|
447
|
-
|
|
448
|
-
name: Site Deployment
|
|
449
|
-
|
|
450
|
-
on
|
|
451
|
-
push
|
|
452
|
-
branches
|
|
453
|
-
- 'release/**'
|
|
454
|
-
- 'master'
|
|
455
|
-
workflow_dispatch
|
|
456
|
-
inputs
|
|
457
|
-
trigger_reason
|
|
458
|
-
description: 'Reason for manual deployment'
|
|
459
|
-
required: false
|
|
460
|
-
type: string
|
|
461
|
-
default: 'Manual deployment'
|
|
462
|
-
|
|
463
|
-
# Prevent concurrent deployments for the same branch
|
|
464
|
-
concurrency
|
|
465
|
-
group: site-deploy-\${{ github.ref }}
|
|
466
|
-
cancel-in-progress: false
|
|
467
|
-
|
|
468
|
-
permissions
|
|
469
|
-
contents: read
|
|
470
|
-
issues: write
|
|
471
|
-
pull-requests: read
|
|
472
|
-
id-token: write # Required for Azure OIDC authentication
|
|
473
|
-
|
|
474
|
-
jobs
|
|
475
|
-
deploy
|
|
476
|
-
name: Deploy to Azure Static Web App
|
|
477
|
-
runs-on: ubuntu-latest
|
|
478
|
-
# Skip deployment on branch creation events
|
|
479
|
-
if: github.event.before != '0000000000000000000000000000000000000000'
|
|
480
|
-
|
|
481
|
-
steps
|
|
482
|
-
- name: Determine deployment environment
|
|
483
|
-
id: environment
|
|
484
|
-
run:
|
|
485
|
-
BRANCH="\${{ github.ref_name }}"
|
|
486
|
-
echo "Branch: $BRANCH"
|
|
487
|
-
|
|
488
|
-
if [ "$BRANCH" == "master" ]; then
|
|
489
|
-
echo "environment=Production" >> $GITHUB_OUTPUT
|
|
490
|
-
echo "environment_name=Production" >> $GITHUB_OUTPUT
|
|
491
|
-
echo "swa_environment=" >> $GITHUB_OUTPUT
|
|
492
|
-
else
|
|
493
|
-
echo "environment=preview" >> $GITHUB_OUTPUT
|
|
494
|
-
echo "environment_name=Preview" >> $GITHUB_OUTPUT
|
|
495
|
-
echo "swa_environment=preview" >> $GITHUB_OUTPUT
|
|
496
|
-
fi
|
|
497
|
-
|
|
498
|
-
- name: Checkout repository
|
|
499
|
-
uses: actions/checkout@v4
|
|
500
|
-
|
|
501
|
-
- name: Read site configuration
|
|
502
|
-
id: config
|
|
503
|
-
run:
|
|
504
|
-
CONFIG_FILE=".dcs/site.yaml"
|
|
505
|
-
|
|
506
|
-
if [ ! -f "$CONFIG_FILE" ]; then
|
|
507
|
-
echo "::error::Missing DCS site configuration file: $CONFIG_FILE"
|
|
508
|
-
exit 1
|
|
509
|
-
fi
|
|
510
|
-
|
|
511
|
-
SITE_NAME=$(grep -E '^site_name:' "$CONFIG_FILE" | sed 's/site_name:\\s*//' | tr -d '"' | tr -d "'")
|
|
512
|
-
SITE_SLUG=$(grep -E '^site_slug:' "$CONFIG_FILE" | sed 's/site_slug:\\s*//' | tr -d '"' | tr -d "'")
|
|
513
|
-
SWA_RESOURCE_ID=$(grep -E '^swa_resource_id:' "$CONFIG_FILE" | sed 's/swa_resource_id:\\s*//' | tr -d '"' | tr -d "'")
|
|
514
|
-
PORTAL_API_URL=$(grep -E '^portal_api_url:' "$CONFIG_FILE" | sed 's/portal_api_url:\\s*//' | tr -d '"' | tr -d "'")
|
|
515
|
-
PORTAL_API_URL="\${PORTAL_API_URL:-https://portal.duffcloudservices.com}"
|
|
516
|
-
GOOGLE_ANALYTICS_ID=$(grep -E '^google_analytics_id:' "$CONFIG_FILE" | sed 's/google_analytics_id:\\s*//' | tr -d '"' | tr -d "'")
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
echo "
|
|
538
|
-
echo "
|
|
539
|
-
echo "
|
|
540
|
-
echo "
|
|
541
|
-
echo "
|
|
542
|
-
echo "
|
|
543
|
-
echo "
|
|
544
|
-
echo "
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
EOF
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
444
|
+
var site_deploy_default = `# Site Deployment Workflow
|
|
445
|
+
# Generated by @duffcloudservices/cli
|
|
446
|
+
# This workflow deploys the site to Azure Static Web Apps using OIDC authentication.
|
|
447
|
+
|
|
448
|
+
name: Site Deployment
|
|
449
|
+
|
|
450
|
+
on:
|
|
451
|
+
push:
|
|
452
|
+
branches:
|
|
453
|
+
- 'release/**'
|
|
454
|
+
- 'master'
|
|
455
|
+
workflow_dispatch:
|
|
456
|
+
inputs:
|
|
457
|
+
trigger_reason:
|
|
458
|
+
description: 'Reason for manual deployment'
|
|
459
|
+
required: false
|
|
460
|
+
type: string
|
|
461
|
+
default: 'Manual deployment'
|
|
462
|
+
|
|
463
|
+
# Prevent concurrent deployments for the same branch
|
|
464
|
+
concurrency:
|
|
465
|
+
group: site-deploy-\${{ github.ref }}
|
|
466
|
+
cancel-in-progress: false
|
|
467
|
+
|
|
468
|
+
permissions:
|
|
469
|
+
contents: read
|
|
470
|
+
issues: write
|
|
471
|
+
pull-requests: read
|
|
472
|
+
id-token: write # Required for Azure OIDC authentication
|
|
473
|
+
|
|
474
|
+
jobs:
|
|
475
|
+
deploy:
|
|
476
|
+
name: Deploy to Azure Static Web App
|
|
477
|
+
runs-on: ubuntu-latest
|
|
478
|
+
# Skip deployment on branch creation events
|
|
479
|
+
if: github.event.before != '0000000000000000000000000000000000000000'
|
|
480
|
+
|
|
481
|
+
steps:
|
|
482
|
+
- name: Determine deployment environment
|
|
483
|
+
id: environment
|
|
484
|
+
run: |
|
|
485
|
+
BRANCH="\${{ github.ref_name }}"
|
|
486
|
+
echo "Branch: $BRANCH"
|
|
487
|
+
|
|
488
|
+
if [ "$BRANCH" == "master" ]; then
|
|
489
|
+
echo "environment=Production" >> $GITHUB_OUTPUT
|
|
490
|
+
echo "environment_name=Production" >> $GITHUB_OUTPUT
|
|
491
|
+
echo "swa_environment=" >> $GITHUB_OUTPUT
|
|
492
|
+
else
|
|
493
|
+
echo "environment=preview" >> $GITHUB_OUTPUT
|
|
494
|
+
echo "environment_name=Preview" >> $GITHUB_OUTPUT
|
|
495
|
+
echo "swa_environment=preview" >> $GITHUB_OUTPUT
|
|
496
|
+
fi
|
|
497
|
+
|
|
498
|
+
- name: Checkout repository
|
|
499
|
+
uses: actions/checkout@v4
|
|
500
|
+
|
|
501
|
+
- name: Read site configuration
|
|
502
|
+
id: config
|
|
503
|
+
run: |
|
|
504
|
+
CONFIG_FILE=".dcs/site.yaml"
|
|
505
|
+
|
|
506
|
+
if [ ! -f "$CONFIG_FILE" ]; then
|
|
507
|
+
echo "::error::Missing DCS site configuration file: $CONFIG_FILE"
|
|
508
|
+
exit 1
|
|
509
|
+
fi
|
|
510
|
+
|
|
511
|
+
SITE_NAME=$(grep -E '^site_name:' "$CONFIG_FILE" | sed 's/site_name:\\s*//' | tr -d '"' | tr -d "'")
|
|
512
|
+
SITE_SLUG=$(grep -E '^site_slug:' "$CONFIG_FILE" | sed 's/site_slug:\\s*//' | tr -d '"' | tr -d "'")
|
|
513
|
+
SWA_RESOURCE_ID=$(grep -E '^swa_resource_id:' "$CONFIG_FILE" | sed 's/swa_resource_id:\\s*//' | tr -d '"' | tr -d "'")
|
|
514
|
+
PORTAL_API_URL=$(grep -E '^portal_api_url:' "$CONFIG_FILE" | sed 's/portal_api_url:\\s*//' | tr -d '"' | tr -d "'")
|
|
515
|
+
PORTAL_API_URL="\${PORTAL_API_URL:-https://portal.duffcloudservices.com}"
|
|
516
|
+
GOOGLE_ANALYTICS_ID=$(grep -E '^google_analytics_id:' "$CONFIG_FILE" | sed 's/google_analytics_id:\\s*//' | tr -d '"' | tr -d "'")
|
|
517
|
+
PROD_APPINSIGHTS_CONNECTION_STRING=$(grep -E '^prod_appinsights_connection_string:' "$CONFIG_FILE" | sed 's/prod_appinsights_connection_string:\\s*//' | tr -d '"' | tr -d "'" || true)
|
|
518
|
+
DEV_APPINSIGHTS_CONNECTION_STRING=$(grep -E '^dev_appinsights_connection_string:' "$CONFIG_FILE" | sed 's/dev_appinsights_connection_string:\\s*//' | tr -d '"' | tr -d "'" || true)
|
|
519
|
+
|
|
520
|
+
# Azure Authentication
|
|
521
|
+
AZURE_CLIENT_ID=$(grep -E '^\\s*client_id:' "$CONFIG_FILE" | sed 's/.*client_id:\\s*//' | tr -d '"' | tr -d "'")
|
|
522
|
+
AZURE_TENANT_ID=$(grep -E '^\\s*tenant_id:' "$CONFIG_FILE" | sed 's/.*tenant_id:\\s*//' | tr -d '"' | tr -d "'")
|
|
523
|
+
AZURE_SUBSCRIPTION_ID=$(grep -E '^\\s*subscription_id:' "$CONFIG_FILE" | sed 's/.*subscription_id:\\s*//' | tr -d '"' | tr -d "'")
|
|
524
|
+
|
|
525
|
+
# Build Configuration
|
|
526
|
+
APP_LOCATION=$(grep -E '^\\s*app_location:' "$CONFIG_FILE" | sed 's/.*app_location:\\s*//' | tr -d '"' | tr -d "'")
|
|
527
|
+
OUTPUT_LOCATION=$(grep -E '^\\s*output_location:' "$CONFIG_FILE" | sed 's/.*output_location:\\s*//' | tr -d '"' | tr -d "'")
|
|
528
|
+
|
|
529
|
+
APP_LOCATION="\${APP_LOCATION:-dist}"
|
|
530
|
+
OUTPUT_LOCATION="\${OUTPUT_LOCATION:-.}"
|
|
531
|
+
|
|
532
|
+
if [ -z "$SWA_RESOURCE_ID" ]; then
|
|
533
|
+
echo "::error::Missing swa_resource_id in $CONFIG_FILE"
|
|
534
|
+
exit 1
|
|
535
|
+
fi
|
|
536
|
+
|
|
537
|
+
echo "site_name=$SITE_NAME" >> $GITHUB_OUTPUT
|
|
538
|
+
echo "site_slug=$SITE_SLUG" >> $GITHUB_OUTPUT
|
|
539
|
+
echo "swa_resource_id=$SWA_RESOURCE_ID" >> $GITHUB_OUTPUT
|
|
540
|
+
echo "app_location=$APP_LOCATION" >> $GITHUB_OUTPUT
|
|
541
|
+
echo "output_location=$OUTPUT_LOCATION" >> $GITHUB_OUTPUT
|
|
542
|
+
echo "azure_client_id=$AZURE_CLIENT_ID" >> $GITHUB_OUTPUT
|
|
543
|
+
echo "azure_tenant_id=$AZURE_TENANT_ID" >> $GITHUB_OUTPUT
|
|
544
|
+
echo "azure_subscription_id=$AZURE_SUBSCRIPTION_ID" >> $GITHUB_OUTPUT
|
|
545
|
+
echo "portal_api_url=$PORTAL_API_URL" >> $GITHUB_OUTPUT
|
|
546
|
+
echo "google_analytics_id=$GOOGLE_ANALYTICS_ID" >> $GITHUB_OUTPUT
|
|
547
|
+
echo "prod_appinsights_connection_string=$PROD_APPINSIGHTS_CONNECTION_STRING" >> $GITHUB_OUTPUT
|
|
548
|
+
echo "dev_appinsights_connection_string=$DEV_APPINSIGHTS_CONNECTION_STRING" >> $GITHUB_OUTPUT
|
|
549
|
+
|
|
550
|
+
- name: Azure login via OIDC
|
|
551
|
+
uses: azure/login@v2
|
|
552
|
+
with:
|
|
553
|
+
client-id: \${{ steps.config.outputs.azure_client_id || vars.AZURE_CLIENT_ID }}
|
|
554
|
+
tenant-id: \${{ steps.config.outputs.azure_tenant_id || vars.AZURE_TENANT_ID }}
|
|
555
|
+
subscription-id: \${{ steps.config.outputs.azure_subscription_id || vars.AZURE_SUBSCRIPTION_ID }}
|
|
556
|
+
|
|
557
|
+
- name: Get deployment tokens
|
|
558
|
+
id: tokens
|
|
559
|
+
run: |
|
|
560
|
+
# Get access token for DCS API
|
|
561
|
+
ACCESS_TOKEN=$(az account get-access-token --resource "api://304711b9-8532-4659-beb7-c85726de9ae5" --query accessToken -o tsv)
|
|
562
|
+
|
|
563
|
+
SITE_NAME="\${{ steps.config.outputs.site_name }}"
|
|
564
|
+
SITE_SLUG="\${{ steps.config.outputs.site_slug }}"
|
|
565
|
+
PORTAL_API_URL="\${{ steps.config.outputs.portal_api_url }}"
|
|
566
|
+
|
|
567
|
+
RESPONSE=$(curl -s -X POST "\${PORTAL_API_URL}/api/v1/sites/deployment-tokens" \\
|
|
568
|
+
-H "Authorization: Bearer $ACCESS_TOKEN" \\
|
|
569
|
+
-H "Content-Type: application/json" \\
|
|
570
|
+
-d "{\\"siteName\\": \\"$SITE_NAME\\", \\"siteSlug\\": \\"$SITE_SLUG\\"}")
|
|
571
|
+
|
|
572
|
+
SWA_TOKEN=$(echo $RESPONSE | jq -r .swaToken)
|
|
573
|
+
|
|
574
|
+
if [ -z "$SWA_TOKEN" ] || [ "$SWA_TOKEN" == "null" ]; then
|
|
575
|
+
echo "::error::Failed to retrieve SWA token from DCS API"
|
|
576
|
+
echo "Response: $RESPONSE"
|
|
577
|
+
exit 1
|
|
578
|
+
fi
|
|
579
|
+
|
|
580
|
+
echo "::add-mask::$SWA_TOKEN"
|
|
581
|
+
echo "swa_token=$SWA_TOKEN" >> $GITHUB_OUTPUT
|
|
582
|
+
|
|
583
|
+
- name: Setup Node.js
|
|
584
|
+
uses: actions/setup-node@v4
|
|
585
|
+
with:
|
|
586
|
+
node-version: "22"
|
|
587
|
+
|
|
588
|
+
- name: Install pnpm
|
|
589
|
+
uses: pnpm/action-setup@v4
|
|
590
|
+
|
|
591
|
+
- name: Setup pnpm cache
|
|
592
|
+
uses: actions/cache@v4
|
|
593
|
+
with:
|
|
594
|
+
path: ~/.pnpm-store
|
|
595
|
+
key: \${{ runner.os }}-pnpm-\${{ hashFiles('**/pnpm-lock.yaml') }}
|
|
596
|
+
restore-keys: |
|
|
597
|
+
\${{ runner.os }}-pnpm-
|
|
598
|
+
|
|
599
|
+
- name: Install dependencies
|
|
600
|
+
run: pnpm install --frozen-lockfile
|
|
601
|
+
|
|
602
|
+
- name: Create environment file
|
|
603
|
+
run: |
|
|
604
|
+
cat > .env << EOF
|
|
605
|
+
VITE_APP_VERSION="\${{ github.sha }}"
|
|
606
|
+
VITE_BACKEND_URI="\${{ steps.config.outputs.portal_api_url }}"
|
|
607
|
+
VITE_SITE_SLUG="\${{ steps.config.outputs.site_slug }}"
|
|
608
|
+
VITE_GOOGLE_ANALYTICS_ID="\${{ steps.config.outputs.google_analytics_id }}"
|
|
609
|
+
VITE_PROD_APPINSIGHTS_CONNECTION_STRING="\${{ steps.config.outputs.prod_appinsights_connection_string }}"
|
|
610
|
+
VITE_DEV_APPINSIGHTS_CONNECTION_STRING="\${{ steps.config.outputs.dev_appinsights_connection_string }}"
|
|
611
|
+
EOF
|
|
612
|
+
|
|
613
|
+
- name: Build site
|
|
614
|
+
run: pnpm run build
|
|
615
|
+
|
|
616
|
+
- name: Inject Google Analytics
|
|
617
|
+
if: steps.config.outputs.google_analytics_id != ''
|
|
618
|
+
run: |
|
|
619
|
+
GA_ID="\${{ steps.config.outputs.google_analytics_id }}"
|
|
620
|
+
OUTPUT_DIR="\${{ steps.config.outputs.app_location }}"
|
|
621
|
+
echo "Injecting Google Analytics tag \${GA_ID} into \${OUTPUT_DIR}..."
|
|
622
|
+
find "$OUTPUT_DIR" -name "*.html" -exec sed -i "s|</head>|<script async src=\\"https://www.googletagmanager.com/gtag/js?id=\${GA_ID}\\"></script><script>window.dataLayer=window.dataLayer\\|\\|[];function gtag(){dataLayer.push(arguments)}gtag('js',new Date());gtag('config','\${GA_ID}')</script>\\n</head>|" {} +
|
|
623
|
+
INJECTED=$(grep -rl "googletagmanager" "$OUTPUT_DIR" --include="*.html" | wc -l)
|
|
624
|
+
echo "Injected GA tag into \${INJECTED} HTML file(s)"
|
|
625
|
+
|
|
626
|
+
- name: Deploy to Azure Static Web Apps
|
|
627
|
+
uses: Azure/static-web-apps-deploy@v1
|
|
628
|
+
with:
|
|
629
|
+
azure_static_web_apps_api_token: \${{ steps.tokens.outputs.swa_token }}
|
|
630
|
+
repo_token: \${{ secrets.GITHUB_TOKEN }}
|
|
631
|
+
action: "upload"
|
|
632
|
+
app_location: \${{ steps.config.outputs.app_location }}
|
|
633
|
+
output_location: \${{ steps.config.outputs.output_location }}
|
|
634
|
+
skip_app_build: true
|
|
635
|
+
deployment_environment: \${{ steps.environment.outputs.swa_environment != '' && steps.environment.outputs.swa_environment || '' }}
|
|
619
636
|
`;
|
|
620
637
|
|
|
621
638
|
// src/commands/init.ts
|
|
@@ -2259,10 +2276,14 @@ async function detectFallbackContentSections(page, existingSections) {
|
|
|
2259
2276
|
}
|
|
2260
2277
|
async function capturePageSnapshot(browser, pageInfo, snapshotConfig, siteSlug, validTextKeys, outputDir, verbose) {
|
|
2261
2278
|
const context = await browser.newContext({
|
|
2262
|
-
viewport: snapshotConfig.viewport
|
|
2279
|
+
viewport: snapshotConfig.viewport,
|
|
2280
|
+
ignoreHTTPSErrors: true
|
|
2263
2281
|
});
|
|
2264
2282
|
const page = await context.newPage();
|
|
2265
|
-
const
|
|
2283
|
+
const rawUrl = pageInfo.path.startsWith("http") ? pageInfo.path : `${process.env.SITE_BASE_URL || "http://localhost:5173"}${pageInfo.path}`;
|
|
2284
|
+
const pageUrl = new URL(rawUrl);
|
|
2285
|
+
pageUrl.searchParams.set("dcs-hide-ribbon", "");
|
|
2286
|
+
const url = pageUrl.toString();
|
|
2266
2287
|
if (verbose) {
|
|
2267
2288
|
console.log(` Capturing: ${pageInfo.slug} (${url})`);
|
|
2268
2289
|
}
|
|
@@ -2300,6 +2321,16 @@ async function capturePageSnapshot(browser, pageInfo, snapshotConfig, siteSlug,
|
|
|
2300
2321
|
path: fullPagePath,
|
|
2301
2322
|
fullPage: snapshotConfig.captureFullPage
|
|
2302
2323
|
});
|
|
2324
|
+
const thumbnailViewport = { width: 640, height: 360 };
|
|
2325
|
+
await page.setViewportSize(thumbnailViewport);
|
|
2326
|
+
await page.waitForTimeout(200);
|
|
2327
|
+
const thumbnailPath = path4.join(pageOutputDir, "thumbnail.png");
|
|
2328
|
+
await page.screenshot({
|
|
2329
|
+
path: thumbnailPath,
|
|
2330
|
+
fullPage: false
|
|
2331
|
+
});
|
|
2332
|
+
await page.setViewportSize(snapshotConfig.viewport);
|
|
2333
|
+
await page.waitForTimeout(100);
|
|
2303
2334
|
const sections = [];
|
|
2304
2335
|
const seenDomPaths = /* @__PURE__ */ new Set();
|
|
2305
2336
|
const getAccurateBounds = async (el, sectionType) => {
|
|
@@ -2508,8 +2539,8 @@ async function capturePageSnapshot(browser, pageInfo, snapshotConfig, siteSlug,
|
|
|
2508
2539
|
sections.sort((a, b) => a.bounds.y - b.bounds.y);
|
|
2509
2540
|
return {
|
|
2510
2541
|
pageSlug: pageInfo.slug,
|
|
2511
|
-
|
|
2512
|
-
|
|
2542
|
+
path: pageInfo.path,
|
|
2543
|
+
type: pageInfo.config.type,
|
|
2513
2544
|
deletable: pageInfo.config.deletable,
|
|
2514
2545
|
title: title || pageInfo.config.title,
|
|
2515
2546
|
capturedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -2600,6 +2631,7 @@ async function captureSnapshotsCommand(options) {
|
|
|
2600
2631
|
const browser = await chromium.launch();
|
|
2601
2632
|
spinner.succeed("Browser launched");
|
|
2602
2633
|
const snapshots = [];
|
|
2634
|
+
const failures = [];
|
|
2603
2635
|
for (const pageInfo of pagesToCapture) {
|
|
2604
2636
|
const pageSpinner = ora3(`Capturing ${pageInfo.slug}...`).start();
|
|
2605
2637
|
try {
|
|
@@ -2618,23 +2650,27 @@ async function captureSnapshotsCommand(options) {
|
|
|
2618
2650
|
fs4.writeFileSync(snapshotPath, JSON.stringify(snapshot, null, 2));
|
|
2619
2651
|
pageSpinner.succeed(`${pageInfo.slug}: ${snapshot.sections.length} sections captured`);
|
|
2620
2652
|
} catch (error) {
|
|
2653
|
+
const message = `${pageInfo.slug}: ${error.message}`;
|
|
2654
|
+
failures.push(message);
|
|
2621
2655
|
pageSpinner.fail(`${pageInfo.slug}: Failed - ${error.message}`);
|
|
2622
2656
|
}
|
|
2623
2657
|
}
|
|
2624
2658
|
await browser.close();
|
|
2625
2659
|
const manifest = {
|
|
2626
2660
|
siteSlug: config2.siteSlug,
|
|
2627
|
-
|
|
2661
|
+
capturedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2662
|
+
capturedVersion: process.env.GITHUB_SHA,
|
|
2628
2663
|
deploymentRef: process.env.GITHUB_REF || "local",
|
|
2629
2664
|
pagesConfigVersion: config2.version,
|
|
2630
2665
|
pages: snapshots.map((s) => ({
|
|
2631
2666
|
pageSlug: s.pageSlug,
|
|
2632
|
-
pagePath: s.
|
|
2633
|
-
pageType: s.
|
|
2667
|
+
pagePath: s.path,
|
|
2668
|
+
pageType: s.type,
|
|
2634
2669
|
deletable: s.deletable,
|
|
2635
2670
|
title: s.title,
|
|
2636
2671
|
capturedAt: s.capturedAt,
|
|
2637
|
-
sectionCount: s.sections.length
|
|
2672
|
+
sectionCount: s.sections.length,
|
|
2673
|
+
hasSnapshot: true
|
|
2638
2674
|
}))
|
|
2639
2675
|
};
|
|
2640
2676
|
const manifestPath = path4.join(outputDir, config2.siteSlug, "manifest.json");
|
|
@@ -2642,10 +2678,13 @@ async function captureSnapshotsCommand(options) {
|
|
|
2642
2678
|
console.log("");
|
|
2643
2679
|
console.log(chalk7.green("\u2705 Snapshot capture complete!"));
|
|
2644
2680
|
console.log(chalk7.gray(` Captured ${snapshots.length} pages`));
|
|
2645
|
-
console.log(chalk7.gray(` - Static: ${snapshots.filter((s) => s.
|
|
2646
|
-
console.log(chalk7.gray(` - Index: ${snapshots.filter((s) => s.
|
|
2647
|
-
console.log(chalk7.gray(` - Dynamic: ${snapshots.filter((s) => s.
|
|
2681
|
+
console.log(chalk7.gray(` - Static: ${snapshots.filter((s) => s.type === "static").length}`));
|
|
2682
|
+
console.log(chalk7.gray(` - Index: ${snapshots.filter((s) => s.type === "index").length}`));
|
|
2683
|
+
console.log(chalk7.gray(` - Dynamic: ${snapshots.filter((s) => s.type === "dynamic").length}`));
|
|
2648
2684
|
console.log(chalk7.gray(` Output: ${outputDir}`));
|
|
2685
|
+
if (failures.length > 0) {
|
|
2686
|
+
throw new Error(`Snapshot capture failed for ${failures.length} page(s): ${failures.join("; ")}`);
|
|
2687
|
+
}
|
|
2649
2688
|
}
|
|
2650
2689
|
|
|
2651
2690
|
// src/index.ts
|