Files
landing-builder/README.md
T
jaybe 86155c9fd3
Auto PR / open-pr (push) Successful in 16s
Auto Label PR / add-automerge-label (pull_request) Successful in 5s
CI / test (pull_request) Successful in 1m11s
feat: verifyIntegrity CLI 래퍼 추가 및 문서화 (TDD)
- verify.cli.ts/verify.cli.test.ts 추가
- README 사용법/종료코드/CI 가이드 문서화
- 전체 테스트 그린 유지
2025-11-16 20:24:30 +09:00

6.0 KiB

This is a Next.js project bootstrapped with create-next-app.

Getting Started

First, run the development server:

npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev

Open http://localhost:3000 with your browser to see the result.

You can start editing the page by modifying app/page.tsx. The page auto-updates as you edit the file.

This project uses next/font to automatically optimize and load Geist, a new font family for Vercel.

Learn More

To learn more about Next.js, take a look at the following resources:

You can check out the Next.js GitHub repository - your feedback and contributions are welcome!

Deploy on Vercel

The easiest way to deploy your Next.js app is to use the Vercel Platform from the creators of Next.js.

Check out our Next.js deployment documentation for more details.

Export Bundle (Landing ZIP)

The Builder can export a production-ready ZIP that contains:

  • index.html, styles.css, app.js
  • assets/ hashed assets (optionally grouped by type)
  • site.webmanifest, robots.txt
  • Optional: sheets/ (Google Apps Script template)
  • Metadata files: assets.json, assets.index.json
    • Integrity: assets.integrity.index.json

Export Options UI

  • Manifest
    • Name, Short Name, Start URL, Display (dropdown), Theme Color (HEX only)
  • Robots
    • Disallow lines (textarea). Each line becomes a Disallow: rule.
    • Robots Meta: <meta name="robots" content="..."> value (e.g. noindex, nofollow). Empty disables the tag.
  • Google Sheets Template Mode
    • Auto: include when form.actionUrl is empty
    • Include: always include
    • Exclude: never include
  • Font Optimization
    • Preconnect: toggle inclusion of Google Fonts preconnect links.
    • Preload: preload & load Google Fonts stylesheet with media="print" onload pattern.
  • Image Options
    • Loading: lazy (default) or eager for <img loading>
    • Decoding: async (default) or sync for <img decoding>
    • Fetch Priority: optional high|low for <img fetchpriority>
    • Srcset/Sizes: optional responsive sources via <img srcset> and <img sizes>
    • Auto Sizes: when enabled and only srcset is provided, a sensible default is applied to <img sizes>: (max-width: 640px) 100vw, 600px
    • Sizes Preset: choose a preset for <img sizes> when imageSizes is not set.
      • mobile-first: (max-width: 640px) 100vw, 800px
      • desktop-fixed: 1200px
    • Precedence: explicit imageSizes > imageSizesPreset > imageAutoSizes > none

site.webmanifest and robots.txt

  • site.webmanifest is derived from page data; Export Options can override fields.
  • robots.txt defaults to a permissive header and adds Disallow lines from UI.
  • meta name="robots" can be injected via Export Options and is written in <head>.

Asset paths and grouping

  • AssetManager writes files to assets/ with stable hash-based filenames.

verifyIntegrity CLI

  • Purpose: Validate exported bundle assets against assets.integrity.index.json.
  • Input format: two JSON files mapping file path → base64 bytes
    • Extras JSON: must contain "assets.integrity.index.json" key with base64 of the index file
    • Assets JSON: keys are asset paths, values are base64 of file bytes
  • Usage:
node scripts/verify.js --extras extras.json --assets assets.json
  • Output: prints a JSON with fields of VerifyResult (ok, errors, summary)

  • Exit codes:

    • 0: ok
    • 1: verification failed or invalid inputs
    • 2: usage error (missing args)
  • CI: add a step to run the CLI after build/export; fail the job if exit code != 0.

  • Path strategy can be configured:

    • flat (default): assets/<hash>.<ext>
    • grouped: assets/images/..., assets/fonts/..., assets/other/...

assets.json

Structured metadata for all assets. Example fields per entry:

  • originalName, mimeType, size
  • hash8, ext, zipPath
  • integrity: sha256-<base64> (placeholder, base64 of bytes)
  • group: images|fonts|other
  • referencedAt: array of local:<originalName> when referenced by the page

assets.index.json

Simple index to quickly find assets by group:

  • images: string[] of zip paths
  • fonts: string[] of zip paths
  • other: string[] of zip paths

assets.integrity.index.json

  • entries: array of { path, integrity, size }
    • path: asset zipPath (e.g. assets/abcd1234.png or grouped assets/images/...)
    • integrity: sha256-<base64> (real SHA-256 of the asset bytes)
    • size: byte length of the asset
  • bundleHash: sha256-<base64> over a deterministic join of path and integrity for all entries

Usage:

  • Verify file-level integrity by recomputing SHA-256(base64) of each asset and comparing with entries[].integrity.
  • Verify file size matches entries[].size.
  • Verify bundle integrity by recomputing bundleHash from sorted entries; useful for quick tamper detection.

Example (Node):

import { verifyIntegrity } from '@/lib/exporter/verify'

// extras must include 'assets.integrity.index.json', assets is a map of zipPath -> bytes
const result = verifyIntegrity(extras, assets)
if (!result.ok) {
  console.error('Integrity check failed:', result.errors)
}
console.log('Summary:', result.summary)
// { total, missing, integrityMismatches, sizeMismatches, bundleHashMismatch }

Google Sheets template (optional)

  • When included, ZIP contains:
    • sheets/Code.gs: minimal Apps Script handler (Web App)
    • sheets/README.txt: setup instructions
  • Inclusion is controlled by sheetsMode (Auto/Include/Exclude) and form.actionUrl in Auto mode.