Skip to content

.phony Package Format

The .phony package is a portable, self-contained data generation unit. It bundles everything needed to generate data: schemas, models, lists, and templates.

Overview

┌─────────────────────────────────────────────────────────────────────────┐
│           .PHONY PACKAGE: Self-Contained Generation Unit                 │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  ANALOGY:                                                                │
│                                                                          │
│  npm package    → JavaScript code + dependencies                         │
│  Docker image   → Application + runtime + dependencies                   │
│  .phony package → Schema + models + lists + templates                   │
│                                                                          │
│  ═══════════════════════════════════════════════════════════════════════ │
│                                                                          │
│  KEY BENEFITS:                                                           │
│                                                                          │
│  • PORTABLE: Same package works on CLI, PHP, Python, Cloud              │
│  • VERSIONED: Semantic versioning, reproducible builds                  │
│  • OFFLINE: All dependencies bundled, no network needed                 │
│  • SHAREABLE: Publish to registry, share with team                      │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

Package Structure

A .phony file is a gzip-compressed tar archive (.tar.gz):

my-package.phony
├── manifest.json           # Package metadata
├── schema.pdl.json         # PDL schema definition

├── models/                 # N-gram model files
│   ├── person/
│   │   ├── first_names.ngram
│   │   └── last_names.ngram
│   ├── business/
│   │   └── company_names.ngram
│   └── address/
│       └── street_names.ngram

├── lists/                  # Static data files
│   ├── geo/
│   │   ├── countries.json
│   │   ├── cities.json
│   │   └── districts.json
│   └── commerce/
│       ├── categories.json
│       └── payment_methods.json

└── templates/              # Complex template files (optional)
    └── documents/
        └── invoice.yaml

Manifest File

The manifest.json contains package metadata:

json
{
  "name": "@phony/ecommerce-tr",
  "version": "1.2.0",
  "description": "Turkish e-commerce data generation package",

  "locale": "tr_TR",
  "locale_independent": false,

  "author": {
    "name": "Phony Team",
    "email": "team@phony.cloud",
    "url": "https://phony.cloud"
  },

  "license": "MIT",

  "dependencies": {
    "@phony/base": "^1.0.0"
  },

  "peerDependencies": {
    "phony": ">=1.0.0"
  },

  "keywords": ["ecommerce", "turkish", "retail", "orders", "products"],

  "repository": {
    "type": "git",
    "url": "https://github.com/phonycloud/packages"
  },

  "build": {
    "created_at": "2024-03-15T10:00:00Z",
    "phony_version": "1.2.0",
    "checksum": "sha256:a1b2c3d4e5f6..."
  },

  "engines": {
    "phony": ">=1.0.0"
  },

  "exports": {
    "entities": ["User", "Product", "Order", "OrderItem"],
    "generators": ["first_name", "last_name", "email", "phone", "address"]
  }
}

Model Files (.ngram)

N-gram model files are gzipped JSON. See N-gram Models for the complete format specification.

json
{
  "version": 1,
  "metadata": {
    "locale": "tr_TR",
    "domain": "person_names",
    "ngram_order": 4,
    "token_type": "char",
    "trained_on": "2024-03-15T10:00:00Z",
    "sample_count": 50000
  },
  "config": {
    "min_word_length": 3,
    "fallback": "prefix"
  },
  "ngrams": ["mehm", "ehme", "hmet", "ayşe", ...],
  "distributions": {
    "word_lengths": { "e": [4, 5, 6], "w": [120, 350, 280], "cw": [120, 470, 750] }
  },
  "first": { "e": [0, 3, 4], "w": [100, 80, 60], "cw": [100, 180, 240] },
  "graph": {
    "0": {
      "c": { "e": [1], "w": [4], "cw": [4] },
      "lc": { "e": [2], "w": [3], "cw": [3] }
    }
  },
  "words": {
    "excluded": [[0, 1, 2], [3]],
    "real": [[0, 1, 2], [3], [4, 5, 6]]
  }
}

Key structure:

  • ngrams: All unique N-gram strings (single source of truth)
  • graph: Markov chain transitions (c = children, lc = lastChildren)
  • words.excluded/real: Words as N-gram index sequences (no string duplication)

List Files

Simple Array

json
["İstanbul", "Ankara", "İzmir", "Bursa", "Antalya"]

Weighted Array

json
[
  { "value": "İstanbul", "weight": 40 },
  { "value": "Ankara", "weight": 20 },
  { "value": "İzmir", "weight": 15 },
  { "value": "Bursa", "weight": 10 },
  { "value": "Antalya", "weight": 15 }
]

Object Array (with metadata)

json
[
  {
    "name": "İstanbul",
    "plate_code": "34",
    "region": "Marmara",
    "population": 15840900
  },
  {
    "name": "Ankara",
    "plate_code": "06",
    "region": "İç Anadolu",
    "population": 5747325
  }
]

Creating Packages

Using CLI

bash
# Initialize new package
phony packages create my-package
# Creates:
#   my-package/
#   ├── manifest.json
#   ├── schema.pdl.json
#   ├── models/
#   ├── lists/
#   └── templates/

# Train models and add to package
phony train names.txt -o my-package/models/names.ngram

# Add list data
cp cities.json my-package/lists/geo/

# Build package
phony packages build my-package
# Creates: my-package-1.0.0.phony

# Validate package
phony packages validate my-package-1.0.0.phony

Package Commands

bash
# List installed packages
phony packages list

# Search registry
phony packages search ecommerce

# Install from registry
phony packages install @phony/ecommerce-tr

# Install specific version
phony packages install @phony/ecommerce-tr@1.2.0

# Install from file
phony packages install ./my-package-1.0.0.phony

# Install from URL
phony packages install https://example.com/packages/my-package.phony

# Update packages
phony packages update

# Remove package
phony packages remove @phony/ecommerce-tr

# Show package info
phony packages info @phony/ecommerce-tr

# Create package
phony packages create my-package

# Build package
phony packages build ./my-package

# Publish to registry (requires auth)
phony packages publish ./my-package-1.0.0.phony

Package Registry

Official Registry

The official Phony package registry at registry.phony.cloud:

bash
# Configure registry
phony config set registry https://registry.phony.cloud

# Login to publish
phony login

Package Naming

@scope/package-name

Examples:
@phony/ecommerce-tr      # Official Phony package
@phony/healthcare-us     # Official Phony package
@community/fintech-eu    # Community contributed
@yourcompany/internal    # Private company package
my-local-package         # Unscoped local package

Versioning

Packages follow Semantic Versioning:

MAJOR.MINOR.PATCH

1.0.0 → Initial release
1.1.0 → New features (backward compatible)
1.1.1 → Bug fixes
2.0.0 → Breaking changes

Package Dependencies

Inheritance

Packages can inherit from other packages:

json
{
  "inherits": "@phony/base"
}

Resolution order:

  1. Current package
  2. Inherited package(s)
  3. Base package

Dependency Declaration

json
{
  "dependencies": {
    "@phony/base": "^1.0.0",
    "@phony/geo-tr": "~1.2.0",
    "@phony/names-tr": "1.3.0"
  }
}

Version Ranges

SyntaxMeaning
1.2.3Exact version
^1.2.3Compatible with 1.x.x (>=1.2.3 <2.0.0)
~1.2.3Compatible with 1.2.x (>=1.2.3 <1.3.0)
>=1.2.3Greater than or equal
<2.0.0Less than
1.2.xAny 1.2.x version
*Any version

Package Size Optimization

Model Compression

Models are automatically compressed:

StageSizeCompression
Raw JSON~8 MB-
Minified~6 MB25%
Gzipped~1.5 MB81%

List Optimization

json
// Instead of repeating strings
{
  "cities": [
    { "name": "İstanbul", "region": "Marmara" },
    { "name": "Ankara", "region": "İç Anadolu" }
  ]
}

// Use string tables for large lists
{
  "_strings": {
    "regions": ["Marmara", "İç Anadolu", "Ege"]
  },
  "cities": [
    { "name": "İstanbul", "region": 0 },
    { "name": "Ankara", "region": 1 }
  ]
}

Selective Loading

Runtimes load only what's needed:

javascript
// Only loads User-related generators
const user = await package.generateOne('User');

// Only loads Order-related data
const order = await package.generateOne('Order');

Security

Checksums

Packages include SHA-256 checksums:

json
{
  "build": {
    "checksum": "sha256:a1b2c3d4e5f6g7h8i9j0..."
  }
}

Verified on install:

bash
$ phony packages install @phony/ecommerce-tr
Downloading @phony/ecommerce-tr@1.2.0...
Verifying checksum...
Installing...

Signing (Future)

Package signing for verified publishers:

json
{
  "signature": {
    "algorithm": "ed25519",
    "public_key": "...",
    "signature": "..."
  }
}

Examples

Minimal Package

minimal.phony/
├── manifest.json
└── schema.pdl.json

manifest.json:

json
{
  "name": "minimal",
  "version": "1.0.0",
  "locale": "en_US"
}

schema.pdl.json:

json
{
  "$schema": "https://phony.cloud/schemas/pdl-1.0.json",
  "version": "1.0",
  "locale": "en_US",
  "name": "Minimal Package",

  "generators": {
    "random_id": {
      "type": "logic",
      "algorithm": "uuid_v4"
    },
    "random_name": {
      "type": "list",
      "source": "inline",
      "values": ["Alice", "Bob", "Charlie"]
    }
  },

  "entities": {
    "User": {
      "fields": {
        "id": { "generator": "random_id" },
        "name": { "generator": "random_name" }
      }
    }
  }
}

Full E-Commerce Package

See the PDL Specification for a complete e-commerce example.

Phony Cloud Platform Specification