stacksjs

stacks-faker

Use when working with fake data generation in a Stacks application - seeding databases, generating test data, model factories, or using faker utilities. Covers @stacksjs/faker (wrapper around ts-mocker) and its integration with the database seeder.

stacksjs 636 20 Updated 2w ago
GitHub

Install

npx skillscat add stacksjs/stacks/stacks-faker

Install via the SkillsCat registry.

SKILL.md

Stacks Faker

@stacksjs/faker wraps ts-mocker with a @faker-js/faker-compatible API plus enhanced modules for vehicle, company, lorem, location, datatype, and helpers.

Key Paths

  • Core package: storage/framework/core/faker/src/
  • Source: storage/framework/core/faker/src/index.ts
  • Tests: storage/framework/core/faker/tests/faker.test.ts
  • Seeder integration: storage/framework/core/database/src/seeder.ts

Usage

import { faker } from '@stacksjs/faker'

faker.person.fullName()        // 'John Smith'
faker.internet.email()         // 'john.smith@example.com'
faker.lorem.sentence()         // 'Lorem ipsum dolor sit amet.'
faker.number.int({ min: 1, max: 100 })  // 42
faker.datatype.uuid()          // 'a1b2c3d4-...'
faker.vehicle.vrm()            // 'AB12 CDE'

Modules

datatype (Compatibility Layer)

faker.datatype.boolean(): boolean
faker.datatype.number(options?: { min?: number, max?: number }): number
faker.datatype.float(options?: { min?: number, max?: number, precision?: number }): number
faker.datatype.uuid(): string
faker.datatype.string(length?: number): string           // default: 10
faker.datatype.array<T>(generator: () => T, length?: number): T[]

location

faker.location.street(): string
faker.location.streetAddress(useFullAddress?: boolean): string
faker.location.city(): string
faker.location.state(): string
faker.location.stateAbbr(): string
faker.location.country(): string
faker.location.countryCode(): string
faker.location.zipCode(): string
faker.location.latitude(options?: { min?, max?, precision? }): number
faker.location.longitude(options?: { min?, max?, precision? }): number
faker.location.direction(): string
faker.location.buildingNumber(): string

company

faker.company.name(): string
faker.company.catchPhrase(): string
faker.company.buzzPhrase(): string

vehicle (Fully Custom)

faker.vehicle.vrm(): string             // UK Registration: 'AB12 CDE'
faker.vehicle.vehicle(): string          // 'Toyota Camry'
faker.vehicle.type(): string             // Sedan, SUV, Truck, Van, Coupe, etc.
faker.vehicle.manufacturer(): string     // Toyota, Honda, Ford, BMW, Tesla, etc.
faker.vehicle.model(): string            // Camry, Accord, F-150, Model 3, etc.
faker.vehicle.fuel(): string             // Gasoline, Diesel, Electric, Hybrid
faker.vehicle.vin(): string              // 17-character VIN
faker.vehicle.color(): string            // Black, White, Silver, Red, Blue, etc.

helpers

faker.helpers.arrayElement<T>(array: T[]): T
faker.helpers.arrayElements<T>(array: T[], count?: number): T[]
faker.helpers.shuffle<T>(array: T[]): T[]
faker.helpers.maybe<T>(cb: () => T, options?: { probability?: number }): T | undefined
faker.helpers.objectKey<T>(obj: T): keyof T
faker.helpers.objectValue<T>(obj: T): T[keyof T]

lorem

faker.lorem.word(): string
faker.lorem.words(count?: number): string              // default: 3
faker.lorem.sentence(wordCount?: number | { min, max }): string
faker.lorem.sentences(count?, separator?): string      // default: 3, sep: ' '
faker.lorem.paragraph(sentenceCount?): string
faker.lorem.paragraphs(count?: number | { min, max }, separator?): string
faker.lorem.text(length?: number): string              // default: 200 chars
faker.lorem.slug(wordCount?: number): string           // URL-safe, default: 3
faker.lorem.lines(count?: number): string              // default: 3

Inherited from ts-mocker

faker.commerce.department() / .price() / .productName() / .productDescription()
faker.date.past() / .future() / .recent() / .soon()
faker.finance.creditCardNumber()
faker.image.avatar() / .url()
faker.internet.email() / .ip() / .mac() / .url() / .userAgent()
faker.number.int() / .float()
faker.person.fullName()
faker.phone.number()
faker.string.alpha() / .alphanumeric() / .numeric() / .uuid()
faker.system.fileName() / .filePath() / .fileType()
faker.word.adjective() / .noun()

Seeder Integration

Model attributes declare a factory function receiving faker:

import { schema } from '@stacksjs/validation'

// Attribute entries inside defineModel({ attributes: ... })
const attributes = {
  name: {
    validation: { rule: schema.string().min(3).max(255) },
    factory: faker => faker.company.name(),
  },
  status: {
    validation: { rule: schema.enum(['active', 'inactive']) },
    factory: faker => faker.helpers.arrayElement(['active', 'inactive']),
  },
}

How Seeding Works

  1. Model needs traits: { useSeeder: { count: N } }
  2. generateRecord() calls attr.factory(faker, generated) for each attribute;
    generated contains earlier declared attributes before password hashing
  3. Falls back to attr.default if factory fails
  4. Converts camelCase → snake_case for DB columns
  5. Auto-hashes password fields (bcrypt)
  6. Inserts in batches of 100
  7. Model dependencies determine seeding order, so included parent models seed
    before their dependents. Application Seeder classes additionally use static
    order and tags; read stacks-database for that separate pass.

Smart Default Inference (when a factory throws and has no explicit default)

  • is*, has*, *able → false
  • *count, *amount, *quantity → 0
  • *url, *link → 'https://example.com'
  • *email → faker.internet.email()
  • *name → faker.person.fullName()
  • Unknown → null

An attribute with neither factory nor default is skipped, not filled by this
inference. App models override framework models even when opting out of model
seeding. Auth/account models are protected from routine seeding; review the
actual protected-model and includeDefaults/fresh/allowProtected behavior before
choosing a destructive development reset. Seed records are fixture data, not
random values suitable for real credentials or financial claims.

Gotchas

  • Not @faker-js/faker - wrapper around ts-mocker. Most APIs compatible but not all
  • Custom modules override base - lorem, datatype, location, company, vehicle, helpers are custom
  • Vehicle module is fully custom - hardcoded manufacturer/model lists, not from ts-mocker
  • Factory receives context - (faker, generated) => value can use fields
    declared earlier in the same model; do not depend on fields declared later.
  • Password detection is heuristic - by password-like names, or a hidden
    attribute whose name also includes pass; hidden alone does not hash a field.
  • Seeder batch size is 100 - records inserted in chunks
  • Model seeding order matters - the dependency graph drives parent ordering.

Categories