npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@c-time/frelio-data-json-generator

v1.2.1

Published

Generate FrelioDataJson from FrelioBuildDataRecipe with incremental build support

Readme

@c-time/frelio-data-json-generator

FrelioBuildDataRecipe に従って FrelioDataJson を生成するライブラリ。

概要

@c-time/frelio-data-json-generator は GitHub Actions で実行され、CMS で編集されたコンテンツを HTML 生成用の JSON ファイル(FrelioDataJson)に変換します。

特徴

  • 差分ビルド: Git diff に基づいて変更されたコンテンツのみを再生成
  • フルリビルド: すべてのコンテンツを再生成(--full-rebuild オプション)
  • 依存マップ: テンプレートやパーツの変更も追跡し、影響を受けるすべての出力を再生成
  • エラーレポート: 一部のコンテンツが生成できなくても処理を継続し、エラーをレポート
  • ドライラン: ファイルを出力せずにレポートのみ生成(--dry-run オプション)

インストール

npm install @c-time/frelio-data-json-generator

CLI 使用例

# 差分ビルド(デフォルト: origin/main...HEAD)
npx tsx scripts/generate-data-json.ts

# フルリビルド(全ファイル再生成)
npx tsx scripts/generate-data-json.ts --full-rebuild

# ドライラン(ファイル出力せずレポートのみ)
npx tsx scripts/generate-data-json.ts --dry-run

# 差分範囲を指定
npx tsx scripts/generate-data-json.ts --diff-range "origin/develop...HEAD"

# ログレベル
npx tsx scripts/generate-data-json.ts --log-level debug
npx tsx scripts/generate-data-json.ts --log-level info   # デフォルト
npx tsx scripts/generate-data-json.ts --log-level quiet

プログラム使用例

import {
  generateDataJson,
  NodeFileSystem,
  getGitDiff,
} from '@c-time/frelio-data-json-generator'
import { readFileSync, writeFileSync, mkdirSync, unlinkSync } from 'fs'
import { dirname, join } from 'path'

// レシピと依存マップを読み込み
const recipe = JSON.parse(
  readFileSync('frelio-data/admin/recipes/build-data-recipe.json', 'utf-8')
)
const dependencyMap = JSON.parse(
  readFileSync('frelio-data/admin/dependency-map.json', 'utf-8')
)

// Git diff を取得
const gitDiff = await getGitDiff('origin/main...HEAD')

// FrelioDataJson を生成
const result = await generateDataJson({
  recipe,
  dependencyMap,
  gitDiff,
  fileSystem: new NodeFileSystem(),
  contentRootPath: 'frelio-data/site',
  outputRootPath: 'frelio-data/generated/data-json',
  options: {
    fullRebuild: false,
    dryRun: false,
    logLevel: 'info',
  },
})

const OUTPUT_ROOT = 'frelio-data/generated/data-json'

// 結果を出力
for (const output of result.outputs) {
  const fullPath = join(OUTPUT_ROOT, output.path)

  if (output.content.type === 'delete') {
    // 削除
    unlinkSync(fullPath)
  } else {
    // 作成/更新
    mkdirSync(dirname(fullPath), { recursive: true })
    writeFileSync(fullPath, JSON.stringify(output.content, null, 2))
  }
}

// レポートを出力
writeFileSync(
  'frelio-data/generated/report.json',
  JSON.stringify(result.report, null, 2)
)

console.log(`Updated: ${result.report.stats.updated}`)
console.log(`Deleted: ${result.report.stats.deleted}`)
console.log(`Errors: ${result.report.stats.errors}`)

出力形式

FrelioDataJson

{
  "type": "update",
  "template": "article/detail.html",
  "outputFile": "articles/my-article.json",
  "data": {
    "contentId": "123e4567-e89b-12d3-a456-426614174000",
    "slug": "my-article",
    "title": "記事タイトル",
    "body": "<p>記事本文...</p>"
  }
}

| フィールド | 説明 | |-----------|------| | type | "update" または "delete" | | template | 使用するテンプレートのパス | | outputFile | 出力先のパス | | data | テンプレートに渡すデータ |

report.json

{
  "generatedAt": "2026-03-28T10:00:00.000Z",
  "mode": "incremental",
  "dryRun": false,
  "stats": {
    "updated": 15,
    "deleted": 2,
    "skipped": 0,
    "errors": 1
  },
  "outputs": [
    { "path": "articles/my-article.json", "status": "updated" },
    { "path": "articles/old-article.json", "status": "deleted" }
  ],
  "errors": [
    {
      "code": "RELATION_NOT_FOUND",
      "outputPath": "articles/broken.json",
      "contentId": "abc-123",
      "field": "relatedCategory",
      "message": "リレーション先 'category/xyz' が見つかりません"
    }
  ],
  "warnings": [
    {
      "code": "EMPTY_LIST",
      "outputPath": "tags/empty-tag.json",
      "message": "リストが空です: tags"
    }
  ]
}

処理フロー

1. Git diff から変更ファイルを検出(または --full-rebuild で全件)
2. dependency-map を使って再生成スコープを計算
3. templateIncludes でパーツ変更の影響を拡張
4. 既存出力をスキャンして削除検出に備える
5. 必要なコンテンツをロード
6. レシピに従って FrelioDataJson を生成
7. 削除対象を検出(今回出力されなかったファイル)
8. レポートを生成

エラーハンドリング

一部のコンテンツが生成できなくても、処理は最後まで継続します。 エラーは report.jsonerrors に記録され、CMS-admin で確認できます。

エラーコード

| コード | 説明 | 対処 | |--------|------|------| | RELATION_NOT_FOUND | リレーション先が見つからない | スキップして継続 | | CONTENT_NOT_FOUND | コンテンツファイルが見つからない | スキップして継続 | | INVALID_TEMPLATE_VAR | outputPath の変数が解決できない | スキップして継続 | | INVALID_JSON | JSON パースエラー | スキップして継続 | | FILTER_ERROR | フィルター条件が不正 | スキップして継続 | | CIRCULAR_REFERENCE | 循環参照を検出 | スキップして継続 | | INVALID_OUTPUT_PATH | パス禁止文字・空文字 | 出力しない | | DUPLICATE_OUTPUT_PATH | 同一パスが複数回生成 | 最初の1つのみ出力 |

警告コード

| コード | 説明 | |--------|------| | EMPTY_LIST | リストが空 | | TRUNCATED_RELATION | limit により一部のリレーションのみ展開 | | DEFAULT_VALUE_USED | デフォルト値を使用 |

オプション

| オプション | CLI フラグ | 説明 | デフォルト | |-----------|-----------|------|-----------| | fullRebuild | --full-rebuild | 全ファイル再生成 | false | | dryRun | --dry-run | ファイル出力せずレポートのみ | false | | logLevel | --log-level | ログレベル (debug/info/quiet) | info |

API リファレンス

generateDataJson(input)

メイン関数。FrelioDataJson を生成します。

function generateDataJson(
  input: GenerateDataJsonInput
): Promise<GenerateDataJsonResult>

入力

| パラメータ | 型 | 説明 | |-----------|---|------| | recipe | FrelioBuildDataRecipe | ビルドレシピ | | dependencyMap | FrelioDependencyMap | 依存マップ | | gitDiff | GitDiffInfo | Git diff 情報 | | fileSystem | FileSystemPort | ファイルシステム | | contentRootPath | string | コンテンツ読み込み元パス | | outputRootPath | string | 出力先ルートパス | | options | GenerateDataJsonOptions | オプション |

出力

| フィールド | 型 | 説明 | |-----------|---|------| | outputs | OutputFile[] | 生成されたファイル一覧 | | report | GenerationReport | ビルドレポート |

getGitDiff(diffRange)

指定した範囲の Git diff を取得してパースします。

function getGitDiff(diffRange: string): Promise<GitDiffInfo>

parseGitDiff(diffText)

git diff --name-status の出力をパースします。

function parseGitDiff(diffText: string): GitDiffInfo

NodeFileSystem

Node.js のファイルシステムを使う FileSystemPort 実装。

class NodeFileSystem implements FileSystemPort {
  readFile(path: string): Promise<string>
  exists(path: string): Promise<boolean>
  listFiles(pattern: string): Promise<string[]>
}

GitHub Actions 設定例

差分ビルド

name: Generate Data JSON

on:
  push:
    branches: [staging-*]
    paths:
      - 'frelio-data/site/**'

jobs:
  generate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0  # 差分比較のため

      - uses: actions/setup-node@v4
        with:
          node-version: '20'

      - run: npm ci
      - run: npx tsx scripts/generate-data-json.ts

      - name: Commit generated files
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"
          git add frelio-data/generated/
          git commit -m "chore: generate data JSON" || true
          git push

フルリビルド(タグベース)

name: Full Rebuild Data JSON

on:
  push:
    tags:
      - 'rebuild-*'

jobs:
  rebuild:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - uses: actions/setup-node@v4
        with:
          node-version: '20'

      - run: npm ci
      - run: npx tsx scripts/generate-data-json.ts --full-rebuild

依存関係

@c-time/frelio-data-json-generator
├── @c-time/frelio-data-json         # 出力型 (FrelioDataJson)
├── @c-time/frelio-data-json-recipe  # レシピ型 (FrelioBuildDataRecipe)
└── @c-time/frelio-dependency-map    # スコープ選定 (FrelioDependencyMap)

ライセンス

Private